Ivailo Karamanolev
Ivailo Karamanolev

Reputation: 823

Django REST framework serializers: multiple fields mapping to one property

I have a model that has a flags property, which is a bitmask of multiple values. I want to expose it as an API using django-rest-framework, where the different flags are different boolean properties. Say, if the flags are FLAG_NEW=1, FLAG_DELETED=2, I want to expose isNew and isDeleted fields. For read-only models, this is easy - just use a SerializerModelField and get whether the flag is set. However, that doesn't work when I want to deserialize (this is a read-only field). I could use a custom field, but then what should I put in the source= parameter? They will overwrite each other if I put source=flags and if I don't, then how do I get the initial value?

class MyModel(models.Model):
    FLAG_NEW = 1
    FLAG_DELETED = 2

    flags = models.IntegerField()

....

class MyModelSerializer(models.Model):
    isDeleted = ???
    isNew = ???

Upvotes: 2

Views: 1653

Answers (1)

morningstar
morningstar

Reputation: 9122

class MyModel(models.Model):
    FLAG_NEW = 1
    FLAG_DELETED = 2

    flags = models.IntegerField(default=0)

    @property
    def isNew(self):
        return self.flags | self.FLAG_NEW

    @isNew.setter
    def isNew(self, value):
        if value:
            self.flags |= self.FLAG_NEW
        else:
            self.flags &= ~self.FLAG_NEW

    @property
    def isDeleted(self):
        return self.flags | self.FLAG_DELETED

    @isDeleted.setter
    def isDeleted(self, value):
        if value:
            self.flags |= self.FLAG_DELETED
        else:
            self.flags &= ~self.FLAG_DELETED

....

class MyModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyModel
        fields = ('id', 'isNew', 'isDeleted', ...)

Upvotes: 2

Related Questions