I am validating data from a request in django's rest framework with data validation in the serializer. I need all error messages to be sent in a single response.
On sending a string that is too long, i get the error:
django.db.utils.DataError: value too long for type character varying(3)
In my model I've defined the max length of the character field as 3 (max theoretically needed).
I've added validation in the serializer to catch requests with too many characters:
validators.py
class CustomUserValidators():
errors_to_return = {}
def val_role(self, role):
if len(role) > 3:
self.errors_to_return["role_length"] = "Ensure this field has no more than 3 characters."
serializers.py
from Sea.validators import CustomUserValidators
class LagoonUserCreateSerializer(UserCreateSerializer, CustomUserValidators):
class Meta:
model = User
fields = ('id', 'username', 'role',)
def validate(self, attrs):
self.val_role(attrs['role'])
if len(self.errors_to_return) > 0:
raise serializers.ValidationError(self.errors_to_return)
return attrs
models.py
class SeaUser(AbstractUser):
...
role = models.CharField(_('Role'), max_length=3)
But the request still returns the error (value too long...
as above). I expected the erorr to be caught in the serializer and the values not passed to the model, why is the value ever reaching the model?
I have researched this, and all the solutions say make the field length 255. This doesn't answer why the value is ever being tested by the model in the first place, and doesn't explain what happend if somehow a longer than expected value does end up in the request.
Any help with this is appreciated.
I would go with different approach and take advantage of serializer's validation.
You can specify custom field-level validation by adding .validate_field methods to your Serializer.
So you can add the following method to your serializer.
def validate_role(self, value):
if len(value) > 3:
raise serializers.ValidationError("Ensure this field has no more than 3 characters")
return value
And remove CustomUserValidators
completely.
As mentioned in the comment, you can move the validation to a utility function and use it everywhere you need.
def validate_user_role(value):
return 0 < len(value) <= 3
You can place this function in a separete module if you like and then you use in your serializer:
def validate_role(self, value):
if not validate_user_role(value):
raise serializers.ValidationError("Ensure this field has no more than 3 characters")
return value
Another, simpler solution to consider is to use serializer's CharField attributes and do this:
class LagoonUserCreateSerializer(UserCreateSerializer):
role = serializers.CharField(min_length=1, max_length=3)
This will validate your input without implementing the validate_role method.
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