12
votes

This is my Model:

class Post(models.Model):
    user = models.ForeignKey(User)
    post = models.CharField(max_length=400)
    country = models.ForeignKey(Country, blank=True, null=True)

and this is my serializer:

class PostSerializer(serializers.ModelSerializer):

    class Meta:
        model = Post
        fields = ('user', 'post', 'country',)

    def create(self, validated_data):
        post = Post(
                user =  User.objects.get(username='MyUser'),
                post = validated_data['post'],
        )

        if validated_data.get('country', None):
            post.country = validated_data['country']

        return post

Is there any way for me to tell DRF that if the value of the field is null (because the 'country' field is optional and sometimes not provided) then to skip it and just serialize the other data? Or at least serialize it with a value of None?

I don't think I can use SerializerMethodField (http://www.django-rest-framework.org/api-guide/fields/#serializermethodfield) because the 'country' field is not a read-only field (I write too it too, if it is provided).

I basically want to omit the field (or at least make the value None) when serializing an object If the field is null.

3

3 Answers

9
votes

As of DRF 3.2.4, so long as you add

blank=True

to the models field like so:

class Post(models.Model):
    country = models.ForeignKey(Country, blank=True)

then DRF will treat the field as optional when serializing and deserializing it (Note though that if there is no null=True on the model field, then Django will raise an error if you try to save an object to the database without providing the field).

See the answer here for more information: DjangoRestFramework - correct way to add "required = false" to a ModelSerializer field?

If you are using pre-DRF 3.2.4, then you can override the field in the serializer and add required=False to it. See the documentation here for more information on specifying or overriding fields explicitily: http://www.django-rest-framework.org/api-guide/serializers/#specifying-fields-explicitly

So something like this (Note that I did not fully test the code below but it should be something along these lines):

class PostSerializer(serializers.ModelSerializer):
    country = serializers.PrimaryKeyRelatedField(required=False)
    class Meta:
        model = Post
        fields = ('user', 'post', 'country',)
6
votes

This thread might be useful:

https://stackoverflow.com/a/28870066/4698253

It basically says that you can override the to_representation() function with a slight modification.

I would have put this in the comments but I don't have enough points yet :(

0
votes

Use allow_null=True:

allow_null - If set to True, the field will accept values of None or the empty string for nullable relationships. Defaults to False.

serializers.py

class PostSerializer(serializers.ModelSerializer):
    tracks = serializers.PrimaryKeyRelatedField(allow_blank=True)

    class Meta:
        model = Post