Getting started using django-rest-framework, and I'm having some trouble regarding validation.
I have a basic model, and i've applied validators to a copple of its fields (A regular MaxLengthValidator
and a custom RegexValidator
, ending up with something like this:
class ZipCodeValidator(RegexValidator): regex = '^([0-9]{5})$' message = u'Invalid ZipCode.' class User(AbstractUser, BaseUser): """ Custom user model """ # ... other fields ... zipcode = models.CharField( max_length=5, blank=True, validators=[ZipCodeValidator()] ) description = models.TextField( null=True, blank=True, max_length=1000, validators=[MaxLengthValidator(1000)] )
I then created a ModelSerializer
mapped to this model, with a few additional fields and methods. This is all served by a very simple `RetrieveUpdateAPIView.
I'm noticing that the validators are not called (i can enter anything in the zipcode field, or exceed 1000 characters for the description).
Quick and dirty solution has been to override the two fields at the serializer level and assigne them the validator there:
class UserSerializer(serializers.ModelSerializer): zipcode = serializers.WritableField( source='zipcode', required=False, validators=[ZipCodeValidator()] ) description = serializers.WritableField( source='description', required=False, validators=[MaxLengthValidator(1000)] )
This works fine, but i don't like it much. I'd rather have this validation occur at the model level to be safer (i wouldn't having mind custom or additional validation on the serializer, but those rules will need to be enforced in all cases). Since serializers work a lot like django forms, i expected them to call the model's clean
& cie method before saving them, but a quick look at the source seems to indicate it does not.
This is a bit annoying, it forces me to duplicate much of the fields code if I want to ensure the validation always happens, and i'd rather keep this as DRY as possible.
I might be missing something, but is there a nice and clean way to ensure those validators will be run by the serializer before updating the model ?
EDIT: Doubled checked the source, turns out that the instance's full_clean
method is indeed called by the view before saving it to the db, which in turns ends up running the model's validator. Still lost as to why those don't seem to run, tho.
Django REST framework is a powerful and flexible toolkit for building Web APIs. Some reasons you might want to use REST framework: The Web browsable API is a huge usability win for your developers. Authentication policies including packages for OAuth1a and OAuth2.
Django is the web development framework in python whereas the Django Rest Framework is the library used in Django to build Rest APIs. Django Rest Framework is especially designed to make the CRUD operations easier to design in Django. Django Rest Framework makes it easy to use your Django Server as an REST API.
337 companies reportedly use Django REST framework in their tech stacks, including Robinhood, UpstageAI, and BirdView.
Django REST framework (DRF) is a powerful and flexible toolkit for building Web APIs. Its main benefit is that it makes serialization much easier. Django REST framework is based on Django's class-based views, so it's an excellent option if you're familiar with Django.
This works for me:
class ZipCodeValidator(RegexValidator): regex = r'^[0-9]{5}$' message = 'Invalid ZipCode.' class MyModel(models.Model): zipcode = models.CharField(max_length=5, blank=True, validators=[ZipCodeValidator()]) class MyModelSerializer(serializers.ModelSerializer): class Meta: model = MyModel >>> s1 = MyModelSerializer(data={'zipcode': '34234'}) >>> s1.is_valid() True >>> s2 = MyModelSerializer(data={'zipcode': 'f3434'}) >>> s2.is_valid() False >>> s2.errors {'zipcode': [u'Invalid ZipCode.']}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With