Skip to content Skip to sidebar Skip to footer

Drf - Raise Exception If Any Defined Field Is None

I need to serialize model to JSON. Then send this JSON to one API. But this API requires some fields to be not None. I have a list of these fields. In this case, let's say it's jus

Solution 1:

Why validation not working?

The validation process undergoes only while Deserialization process (input is a dict like object) and you are trying a Serialization process. In the case of Serialization, DRF assumes the given object is a valid one and hence it doesn't require a validation. Source DRF-serializers


How can we make this happen?

Method-1 Make your user object to a user_data (dict object) and pass it to the serializer and run the validation.

user = User.objects.get(id=1)
dict_user_data = {"first_name": user.first_name, "last_name": user.last_name, "telephone": user.userprofile.telephone}
user_serializer = UserSerializer(data=dict_user_data)
user_serializer.is_valid(True)
user_serializer.data

Method-2 Override the to_representation() method

classUserSerializer(serializers.ModelSerializer):
    telephone = serializers.CharField(source='userprofile.telephone')

    classMeta:
        model = User
        fields = ['first_name', 'last_name', 'telephone']

    def to_representation(self, instance):
        data = super().to_representation(instance)
        for field, value indata.items():
            if value is None:
                raise SomeExceptionHere({field: "can't be None"})
        returndata

Solution 2:

You don't need to. DRF serializers can do that right out the box. If a field is setted to be null=False or required=True, just do this.

data = UserSerializer(data=user_data)
data.is_valid(raise_exception=True

And that is it. A 400 error will be raised.

If you want, you can tweak the error message:

data = UserSerializer(data=user_data)
try:
    data.is_valid(raise_exception=True)
except ValidationError as e:
   return HttpResponse(status_code=400, content=e)

Solution 3:

What you want is not to validate data for de-serialization, but to validate for serialization. Expressions like required=True are all used to validate data for de-serialization. Serialization is handled in to_representation method of Serializer class (which is the base for ModelSerializer)

What you can do is, override to_representation, and have the method raise an exception if a required field value is None.

You may need to further subclass default DRF classes like Field (for a serializer field) and use your custom classes to be able to provide your functionality in a systematic manner. You do not want to rely on required=True for this, because it is used for another purpose already (for de-serialization validation).

What I suggest is, subclass Field class, add a property like "required_for_read", and define your serializer field with this property, using your custom field class. Then, in your overridden to_representation method, look for this property, and raise an exception if the field has this property as True but its value is None

Post a Comment for "Drf - Raise Exception If Any Defined Field Is None"