My serializer based off of ModelSerializer does not call my validate function regardless of whether I define validators = [my_validator]
where my_validator
is a function defined external to the serializer or I def validator(self, attrs)
inside the serializer class but outside of class Meta
.
My model is something like:
def validate_coordinate(value):
print("Hello from validate_coordinate")
#breakpoint()
if value < -180 or value > 180:
raise ValidationError(f"{value} outside range of -180 to 180 degrees")
class SpacexAsset(models.Model):
# Orbit is implemented the "long way" with a class and tuples
# to force the human-readable form to not be title-cased.
class SatelliteOrbitChoices(models.TextChoices):
LEO = "LEO", "LEO"
GEO = "GEO", "GEO"
NoOrbit = "", ""
AssetTypeChoices = models.TextChoices("AssetType",
"Satellite GroundStation")
asset_type = models.CharField(choices=AssetTypeChoices.choices,
max_length=16)
latitude = models.FloatField(validators=[validate_coordinate])
longitude = models.FloatField(validators=[validate_coordinate])
# This field is required only if the asset type is "Satellite"
orbit = models.CharField(choices=SatelliteOrbitChoices.choices,
max_length=8, blank=True)
def __str__(self):
"""A string representation of the asset record name."""
return self.name
My View is:
class SpacexViewSet(viewsets.ModelViewSet):
queryset = SpacexAsset.objects.all()
serializer_class = SpacexAssetSerializer
An abridged version of my serializer is:
def validate2(self, attrs):
print("Hi there from validate2")
breakpoint()
return attrs
class SpacexAssetSerializer(serializers.ModelSerializer):
def validate(self, attrs):
print("Hi there from validate")
breakpoint()
return attrs
class Meta:
model = SpacexAsset
fields = ['asset-type',
'latitude', 'longitude', 'orbit']
extra_kwargs = {
'asset-type': {'source': 'asset_type'},
}
validators = [validate2]
What I expect is that my validator to be called when I use the built-in admin interface to change an asset field value. What I am seeing is nothing.
That is, my validator, whether a declared validator function within my serializer class or a function in the Meta validators list, is not called. No debugging prints are seen, no breakpoints are taken. The print statements in the field validator are seen, so we know that validation does happen at the model level.
I’ve gone so far as to put print/breakpoint statements in the django rest code serializer.py in is_valid(), get_validators(), run_validation, and to_internal_value(), but I don’t see anything, so I’m guessing they are not called, but why?
I’ve re-read the documentation, but there isn’t anything about special cases.
I’ve looked at some previous Stack Overflow postings, but most of the them involved either earlier (built-in) field validation errors causing user-added validation functions like this to be skipped, but again that is not the case here. No errors are reported at all and no messages appear in the window where “manage.py runserver” is running.