I have user table in which have to put unique email constrain on staff users and unique phone constrain on non staff user. Now I want to maintain this constrain in DRF API and in Django admin, how to achieve this without code duplication.
As I see from DRF 3.0 onwards, all validations are performed explicitly for serializer (If I have overwritten unique_validation or clean method to perform conditional validation, I have to write this custom validation separately for serializer as well) so how to write a custom validation that works both for DRF API and Django admin without code duplication ?
If your model doesn't have nested relationships, this should work.
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
But in my case, I have nested models and I need to override create() and update() methods in serializer. My solution to keep validations in only one place:
def create(self, validated_data):
# Remove nested and M2m relationships from validated_data
firstmodel_set = validated_data.pop('firstmodel_set') if 'firstmodel_set' in validated_data else []
.....
# Get instance of project
instance = Project(**validated_data)
instance.clean()
# If clean method doesn't raise any exception, create.
project = instance.save()
......
If you want serialize validations messages .. maybe something like that will help you ...
def validate_instance(instance):
try:
# Call model validation
instance.clean()
except ValidationError as e:
raise serializers.ValidationError(e)
Or you can use Signals and make validations on pre_save(). Take a look in https://docs.djangoproject.com/en/1.10/topics/signals/
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