Where should I do django checks for objects and fields?

I am creating a django application that uses both the Django Rest Framework and simple django views as an entry point for users.

I want to check both the independent fields of my models and the objects as a whole. For example:

  • Field: The entered license fee is correct based on the regular expression function. No relation to other fields.

  • Object: entered zipcode is valid for this country. Refers to the zipcode and country in the model.

For the DRF-API, I use ModelSerializers, which automatically calls all validators that I placed in my model, for example:

class MyModel(models.Model):
    licence_plate = CharField(max_length=20, validators=[LicencePlateValidator])

Since the validator is specified in the model, the POSTS API (because I use ModelSerializer), as well as objects created in the django admin backend, are checked.

But when I want to introduce object level checking, I need to do this in the serializer of the validate () method, which means that objects are checked only in the API.

I will also have to override the model persistence method to validate objects created on the Django admin page.

Question: It seems to me that this is a little messy, is there one point where I can put checks at the object level so that they run in the API and on the admin page, for example, I did with the check at the field level (I only need to put them in my model declaration and everything is processed)

+4
source share
2 answers

Model.clean.

, ModelForm ( admin), django .

, DRF clean, Serializer.validate ( doc ). mixizer serializer:

class ValidateModelMixin(object)
    def validate(self, attrs):
        attrs = super().validate(attrs)
        obj = self.Meta.model(**attrs)
        obj.clean()
        return attrs

class SomeModelSerializer(ValidateModelMixin, serializers.ModelSerializer):
    #...
    class Meta:
        model = SomeModel

:

class DelegateToModelValidator(object):

    def set_context(self, serializer):
        self.model = serializer.Meta.model

    def __call__(self, attrs):
        obj = self.model(**attrs)
        obj.clean()

class SomeModelSerializer(serializers.ModelSerializer):
    #...
    class Meta:
        model = SomeModel
        validators = (
            DelegateToModelValidator(),
        )

:

  • clean
  • mixin/validator
+3

validate_zipcode_with_country(zipcode, country), 2 zipcode country.

validate() clean().

from django.core.exceptions import ValidationError

def validate_zipcode_with_country(zipcode, country):
    # check zipcode is valid for the given country 
    if not valid_zipcode:
        raise ValidationError("Zipcode is not valid for this country.") 

serializers.py validate().

class MySerializer(serializers.ModelSerializer):   

    def validate(self, attrs):
        zipcode = attrs.get('zipcode')
        country = attrs.get('country')
        validate_zipcode_with_country(zipcode, country) # call the function
        ...

clean() .

class MyModel(models.Model):

    def clean(self):        
        validate_zipcode_with_country(self.zipcode, self.country) # call this function
        ...
+3

Source: https://habr.com/ru/post/1610087/


All Articles