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

I have a question about dealing with m2m / through models and their presentation in django rest framework. Let's take a classic example:

models.py:

    from django.db import models

    class Member(models.Model):
        name = models.CharField(max_length = 20)
        groups = models.ManyToManyField('Group', through = 'Membership')

    class Group(models.Model):
        name = models.CharField(max_length = 20)

    class Membership(models.Model):
        member = models.ForeignKey('Member')
        group = models.ForeignKey('Group')
        join_date = models.DateTimeField()

serializers.py:

    imports...

    class MemberSerializer(ModelSerializer):
        class Meta:
            model = Member

    class GroupSerializer(ModelSerializer):
        class Meta:
            model = Group

views.py:

    imports...

    class MemberViewSet(ModelViewSet):
        queryset = Member.objects.all()
        serializer_class = MemberSerializer

    class GroupViewSet(ModelViewSet):
        queryset = Group.objects.all()
        serializer_class = GroupSerializer

When GETing an instance of Member, I successfully receive all of the member's fields and also its groups - however I only get the groups' details, without extra details that comes from the Membership model.

In other words I expect to receive:

    {
       'id' : 2,
       'name' : 'some member',
       'groups' : [
          {
             'id' : 55,
             'name' : 'group 1'
             'join_date' : 34151564
          },
          {
             'id' : 56,
             'name' : 'group 2'
             'join_date' : 11200299
          }
       ]
    }

Note the join_date.

I have tried oh so many solutions, including of course Django Rest-Framework official page about it and no one seems to give a proper plain answer about it - what do I need to do to include these extra fields? I found it more straight-forward with django-tastypie but had some other problems and prefer 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

From: stackoverflow.com/q/17256724