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 just ['telephone']
but it can be much more.
For example:
class UserSerializer(serializers.ModelSerializer):
telephone = serializers.CharField(source='userprofile.telephone')
class Meta:
model = User
fields = ['first_name','last_name','telephone']
Serialization:
>>> UserSerializer(user).data
>>> {'first_name':'Michael','last_name':'Jackson','telephone':None}
Since API
requires some fields like telephone
, I want UserSerializer
to raise ValidationError
when the required field is None
.
So in this case I couldn't serialize user
because telephone
is None
.
I tried many things including adding required=True
to the telephone
but nothing works.
Is there a way to validate
serialized data? Note that I'm not talking about deserialization
.
Why validation not working?
The validation process undergoes only while
Deserialization
process (input is adict
like object) and you are trying aSerialization
process. In the case ofSerialization
, 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.Method-2
Override the
to_representation()
methodWhat 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
You don't need to. DRF serializers can do that right out the box. If a field is setted to be
null=False
orrequired=True
, just do this.And that is it. A 400 error will be raised.
If you want, you can tweak the error message: