Include intermediary (through model) in responses in Django Rest Framework Include intermediary (through model) in responses in Django Rest Framework python python

Include intermediary (through model) in responses in Django Rest Framework


How about.....

On your MemberSerializer, define a field on it like:

groups = MembershipSerializer(source='membership_set', many=True)

and then on your membership serializer you can create this:

class MembershipSerializer(serializers.HyperlinkedModelSerializer):    id = serializers.Field(source='group.id')    name = serializers.Field(source='group.name')    class Meta:        model = Membership        fields = ('id', 'name', 'join_date', )

That has the overall effect of creating a serialized value, groups, that has as its source the membership you want, and then it uses a custom serializer to pull out the bits you want to display.

EDIT: as commented by @bryanph, serializers.field was renamed to serializers.ReadOnlyField in DRF 3.0, so this should read:

class MembershipSerializer(serializers.HyperlinkedModelSerializer):    id = serializers.ReadOnlyField(source='group.id')    name = serializers.ReadOnlyField(source='group.name')    class Meta:        model = Membership        fields = ('id', 'name', 'join_date', )

for any modern implementations


I was facing this problem and my solution (using DRF 3.6) was to use SerializerMethodField on the object and explicitly query the Membership table like so:

class MembershipSerializer(serializers.ModelSerializer):    """Used as a nested serializer by MemberSerializer"""    class Meta:        model = Membership        fields = ('id','group','join_date')class MemberSerializer(serializers.ModelSerializer):    groups = serializers.SerializerMethodField()    class Meta:        model = Member        fields = ('id','name','groups')    def get_groups(self, obj):        "obj is a Member instance. Returns list of dicts"""        qset = Membership.objects.filter(member=obj)        return [MembershipSerializer(m).data for m in qset]

This will return a list of dicts for the groups key where each dict is serialized from the MembershipSerializer. To make it writable, you can define your own create/update method inside the MemberSerializer where you iterate over the input data and explicitly create or update Membership model instances.


NOTE: As a Software Engineer, I love to use Architectures and I have deeply worked on Layered Approach for Development so I am gonna be Answering it with Respect to Tiers.

As i understood the Issue, Here's the Solutionmodels.py

class Member(models.Model):    member_id = models.AutoField(primary_key=True)    member_name = models.CharField(max_length = class Group(models.Model):    group_id = models.AutoField(primary_key=True)    group_name = models.CharField(max_length = 20)    fk_member_id = models.ForeignKey('Member', models.DO_NOTHING,                              db_column='fk_member_id', blank=True, null=True)class Membership(models.Model):    membershipid = models.AutoField(primary_key=True)    fk_group_id = models.ForeignKey('Group', models.DO_NOTHING,                              db_column='fk_member_id', blank=True, null=True)    join_date = models.DateTimeField()

serializers.py

import serializerclass AllSerializer(serializer.Serializer):    group_id = serializer.IntegerField()    group_name = serializer.CharField(max_length = 20)    join_date = serializer.DateTimeField()

CustomModels.py

imports...    class AllDataModel():        group_id = ""        group_name = ""        join_date = ""

BusinessLogic.py

imports ....class getdata(memberid):    alldataDict = {}    dto = []    Member = models.Members.objects.get(member_id=memberid) #or use filter for Name    alldataDict["MemberId"] = Member.member_id    alldataDict["MemberName"] = Member.member_name    Groups = models.Group.objects.filter(fk_member_id=Member)    for item in Groups:        Custommodel = CustomModels.AllDataModel()        Custommodel.group_id = item.group_id        Custommodel.group_name = item.group_name        Membership = models.Membership.objects.get(fk_group_id=item.group_id)        Custommodel.join_date = Membership.join_date        dto.append(Custommodel)    serializer = AllSerializer(dto,many=True)    alldataDict.update(serializer.data)    return alldataDict

You would technically, have to pass the Request to DataAccessLayer which would return the Filtered Objects from Data Access Layer but as I have to Answer the Question in a Fast Manner so i adjusted the Code in Business Logic Layer!