I have a model that references a Generic Relation that I want to serialize in a detailed manner.
class AType(models.Model):
foo = CharField()
class BType(models.Model):
bar = PositiveIntegerField()
class ToSerialize(models.Model):
scope_limit = models.Q(app_label="app", model="atype") | \
models.Q(app_label="app", model="btype")
content_type = models.ForeignKey(ContentType, limit_choices_to=scope_limit)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
I'd like the JSON for the list method of the ToSerialize viewset to look like:
[
{
"atype": { "id": 1, "foo": "a" }
},
{
"atype": { "id": 2, "foo": "b" }
},
{
"btype": { "id": 1, "bar": "1" }
},
{
"btype": { "id": 2, "bar": "2" }
}
]
Is there a way I can have the serializer for the ToSerialize object's viewset produce "conditional fields" based on the content_type/object_id that will achieve this effect?
None of the answers actually answer the question.
The easy thing to do is to add all the fields by default and then remove it at initialisation of the serializer depending on your condition.
In the example below, we don't give back the emails when listing users.
class UserSerializer():
fields = ('username', 'email')
class Meta:
model = User
def __init__(self, *args, **kwargs):
# Don't return emails when listing users
if kwargs['context']['view'].action == 'list':
del self.fields['email']
super().__init__(*args, **kwargs)
Use SerializeMethodField:
class YourSerializer(serializers.ModelSerializer):
your_conditional_field = serializers.SerializerMethodField()
class Meta:
model = ToSerialize
def get_your_conditional_field(self, obj):
# do your conditional logic here
# and return appropriate result
return obj.content_type > obj.object_id
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