lalameat
lalameat

Reputation: 754

Could serializer's to_representation generate multiple output items in DRF 3?

In short, a serializer:

class ReleaseComponentContactSerializer(StrictSerializerMixin, serializers.ModelSerializer):

    component = serializers.SlugRelatedField(source='release_component', slug_field='name',
                                             queryset=ReleaseComponent.objects.all())
    role = serializers.SlugRelatedField(source='contact_role', slug_field='name',
                                    read_only=False, queryset=ContactRole.objects.all())
    contact = ContactField()

    def to_representation(self, instance):

    ...........................
        # I hope return one dict or multiple dict, for first instance it return dict1, for second one it return dict2, dict3
        return ..............

    class Meta:
        model = RoleContact
        fields = ('id', 'component', 'role', contact)

I hope the results is something like dict1, dict2, dict3, NOT dict1, [dict2, dict3]. Is it possible? I think it is what I want.

The original question is I have three models,

class ReleaseComponent(models.Model):

    .................
    global_component            = models.ForeignKey(GlobalComponent)

    name                        = models.CharField(max_length=100)
    contacts        = models.ManyToManyField(Contact,   through='contact.RoleContact', blank=True)

class RoleContact(models.Model):
    contact_role = models.ForeignKey(ContactRole, related_name='role_contacts',
                                     on_delete=models.PROTECT)
    contact      = models.ForeignKey(Contact, related_name='role_contacts',
                                     on_delete=models.PROTECT)
    global_component = models.ForeignKey('component.GlobalComponent', blank=True, null=True,
                                         related_name='role_contacts')
    release_component = models.ForeignKey('component.ReleaseComponent', blank=True, null=True,
                                          related_name='role_contacts')

class GlobalComponent(models.Model):
    """Record generic component"""
    .................................
    contacts        = models.ManyToManyField(Contact, through='contact.RoleContact', blank=True)

If ReleaseComponent don't have contact, it will use its GlobalComponent's contact. So one RoleContact object may be connected to multiple release components, because one RoleContact -> one GlobalComponent -> multiple ReleaseComponent. If ReleaseComponent have a contact and this contact don't share with GlobalComponent, then it must be one RoleContact -> one ReleaseComponent. Generally speaking, with picking queryset, one RoleContact -> one or more ReleaseComponent.

I hope the output format will be consistent. In output, each item corresponding to one ReleaseComponent's one RoleContact information. Even for the RoleContact object for multiple ReleaseComponent objects. I can generate multiple dicts in to_representation, but in final output, this multiple dict will be in a list, like

[dict2, dict3, dict4]

Is it possible to make them out of the list in final output? To be part of:

dict1, dict2, dict3, dict4, dict5, ........ ?

Thanks.

Upvotes: 1

Views: 641

Answers (1)

Rahul Gupta
Rahul Gupta

Reputation: 47876

You can do that in your views after calling serializer.data to modify the serialized data as per your requirements.

You need to do something like:

serialized_data = my_serializer.data  # original serialized data
return_data = [] # final response which will be returned
for item in serialized_data:
    if isinstance(item, list): # check if a list inside serialized data
        return_data += item # add the elements of the list to 'return_data' list
    else:    
        return_data.append(item) # Otherwise just append the item to 'return_data' list

return_data contains the final desired response.

Upvotes: 2

Related Questions