[PR #14175] [CLOSED] Fix #12731: Add custom model validation from forms and serializers #14328

Closed
opened 2025-12-29 23:23:51 +01:00 by adam · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/netbox-community/netbox/pull/14175
Author: @Urth
Created: 11/2/2023
Status: Closed

Base: developHead: 12731-extended-custom-validators


📝 Commits (1)

  • f32a909 Fix #12731: Add custom model validation from forms and serializers

📊 Changes

6 files changed (+147 additions, -4 deletions)

View changed files

📝 netbox/extras/signals.py (+14 -4)
📝 netbox/extras/tests/test_customvalidator.py (+97 -0)
📝 netbox/extras/validators.py (+21 -0)
📝 netbox/netbox/api/serializers/base.py (+5 -0)
📝 netbox/netbox/forms/base.py (+4 -0)
📝 netbox/netbox/signals.py (+6 -0)

📄 Description

Fixes: #12731

This allows for validation of any m2m relation like tags. The CustomValidator receives the cleaned data from the form/serializer. The model instance is not consistently available in the model forms/serializers so is omitted from both.

Note: the available fields can vary per form/serializer for a model. You should always check if a field is defined in the cleaned data. Alternatively the form/serializer class could be given to the validator to help identify the calling stack.

The patch extends the CustomValidator class with 3 validation functions, documentation is still needed.

    def validate_data(self, data):                                              
        """                                                                     
        Custom validation method for model forms and model serializers, to be overridden by the user.
        Validation failures should raise a ValidationError exception.           
        """                                                                     
        return                                                                  
                                                                                
    def validate_form_data(self, data):                                         
        """                                                                     
        Custom validation method for model forms, to be overridden by the user. 
        Validation failures should raise a ValidationError exception.           
        """                                                                     
        return self.validate_data(data)                                         
                                                                                
    def validate_serializer_data(self, data):                                   
        """                                                                     
        Custom validation method for model serializers, to be overridden by the user.
        Validation failures should raise a ValidationError exception.           
        """                                                                     
        return self.validate_data(data)

These functions allow users to validate M2M relations with regular attributes in the form/serializer validation stage. Using this system you can make exclusive tags based on model attributes or validate combinations of M2M relations

class FooSiteValidator(CustomValidator):
    def validate_data(self, data):
        if data['name'] != 'foo':
            for tag in data['tags']:
                if tag.name == 'FOO':
                    self.fail('FOO tag is reserved for site foo', 'tags')

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/netbox-community/netbox/pull/14175 **Author:** [@Urth](https://github.com/Urth) **Created:** 11/2/2023 **Status:** ❌ Closed **Base:** `develop` ← **Head:** `12731-extended-custom-validators` --- ### 📝 Commits (1) - [`f32a909`](https://github.com/netbox-community/netbox/commit/f32a909b9a2d9fb55e4b38fff95547d5a8b32bc4) Fix #12731: Add custom model validation from forms and serializers ### 📊 Changes **6 files changed** (+147 additions, -4 deletions) <details> <summary>View changed files</summary> 📝 `netbox/extras/signals.py` (+14 -4) 📝 `netbox/extras/tests/test_customvalidator.py` (+97 -0) 📝 `netbox/extras/validators.py` (+21 -0) 📝 `netbox/netbox/api/serializers/base.py` (+5 -0) 📝 `netbox/netbox/forms/base.py` (+4 -0) 📝 `netbox/netbox/signals.py` (+6 -0) </details> ### 📄 Description <!-- Thank you for your interest in contributing to NetBox! Please note that our contribution policy requires that a feature request or bug report be approved and assigned prior to opening a pull request. This helps avoid waste time and effort on a proposed change that we might not be able to accept. IF YOUR PULL REQUEST DOES NOT REFERENCE AN ISSUE WHICH HAS BEEN ASSIGNED TO YOU, IT WILL BE CLOSED AUTOMATICALLY. Please specify your assigned issue number on the line below. --> ### Fixes: #12731 <!-- Please include a summary of the proposed changes below. --> This allows for validation of any m2m relation like tags. The CustomValidator receives the cleaned data from the form/serializer. The model instance is not consistently available in the model forms/serializers so is omitted from both. Note: the available fields can vary per form/serializer for a model. You should always check if a field is defined in the cleaned data. Alternatively the form/serializer class could be given to the validator to help identify the calling stack. The patch extends the CustomValidator class with 3 validation functions, documentation is still needed. ```python def validate_data(self, data): """ Custom validation method for model forms and model serializers, to be overridden by the user. Validation failures should raise a ValidationError exception. """ return def validate_form_data(self, data): """ Custom validation method for model forms, to be overridden by the user. Validation failures should raise a ValidationError exception. """ return self.validate_data(data) def validate_serializer_data(self, data): """ Custom validation method for model serializers, to be overridden by the user. Validation failures should raise a ValidationError exception. """ return self.validate_data(data) ``` These functions allow users to validate M2M relations with regular attributes in the form/serializer validation stage. Using this system you can make exclusive tags based on model attributes or validate combinations of M2M relations ```python class FooSiteValidator(CustomValidator): def validate_data(self, data): if data['name'] != 'foo': for tag in data['tags']: if tag.name == 'FOO': self.fail('FOO tag is reserved for site foo', 'tags') ``` --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
adam added the pull-request label 2025-12-29 23:23:51 +01:00
adam closed this issue 2025-12-29 23:23:51 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#14328