DRF Create and Retrieve m2m with through model
Question: I want to save m2m relationship with through model

# models.py

    
    
    from django.db import models
    
    class Student(utils.PersonalDetailsMixin, utils.ContactDetailsMixin, TimeStampedModel):
        guardians = models.ManyToManyField('core.Guardian', through='Relation')
    
    class Relation(models.Model):
        student = models.ForeignKey('core.Student')
        guardian = models.ForeignKey('core.Guardian')
        relation_type = models.CharField(max_length=1, choices=utils.RELATION_CHOICES)
        # Only used when relation_type is Other
        relation_name = models.CharField(max_length=25, null=True, blank=True)
    
        class Meta:
            unique_together = (
                ('student', 'guardian')
            )
    
    class Guardian(utils.PersonalDetailsMixin, utils.ContactDetailsMixin, TimeStampedModel):
        pass
    

# serializers.py

    
    
    class StudentSerializer(serializers.ModelSerializer):
        guardians = GuardianSerializer(many=True)
    
        class Meta:
            model = Student
    
    
    class GuardianSerializer(serializers.ModelSerializer):
        class Meta:
            model = Guardian
    
    class RelationSerializer(serializers.ModelSerializer):
        class Meta:
            model = Relation
    

First:

    
    
    relation_type = serializers.ChoiceField(choices=RELATION_CHOICES)
    relation_name = serializers.CharField(max_length=25, required=False, allow_null=True, allow_blank=True)
    

I tried adding `relation_type` and `relation_name` to `GuardianSerializer` but
got this error

    
    
    Got AttributeError when attempting to get a value for field `relation_type` on serializer `GuardianSerializer`.
    The serializer field might be named incorrectly and not match any attribute or key on the `Guardian` instance.
    Original exception text was: 'Guardian' object has no attribute 'relation_type'.
    

Which is fine DRF should give this error.

Second:

    
    
    class StudentSerializer(serializers.ModelSerializer):
        school = serializers.HiddenField(default='')
        guardians = RelationSerializer(source='relation_set', many=True)
    
    class GuardianSerializer(serializers.ModelSerializer):
        class Meta:
            model = Guardian
    
    class RelationSerializer(serializers.ModelSerializer):
        guardian = GuardianSerializer(many=True)
    
        class Meta:
            model = Relation
    

Added `RelationSerializer` to `StudentSerializer` and `GuardianSerializer` to
`RelationSerializer`

Now I am getting `'Guardian' object is not iterable`

    
    
    Traceback:
    
    File "/home/prime/.virtualenvs/omapi/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
      149.                     response = self.process_exception_by_middleware(e, request)
    
    File "/home/prime/.virtualenvs/omapi/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
      147.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
    
    File "/home/prime/.virtualenvs/omapi/local/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
      58.         return view_func(*args, **kwargs)
    
    File "/home/prime/.virtualenvs/omapi/local/lib/python2.7/site-packages/rest_framework/viewsets.py" in view
      87.             return self.dispatch(request, *args, **kwargs)
    
    File "/home/prime/.virtualenvs/omapi/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
      466.             response = self.handle_exception(exc)
    
    File "/home/prime/.virtualenvs/omapi/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
      463.             response = handler(request, *args, **kwargs)
    
    File "/home/prime/.virtualenvs/omapi/local/lib/python2.7/site-packages/rest_framework/mixins.py" in list
      48.         return Response(serializer.data)
    
    File "/home/prime/.virtualenvs/omapi/local/lib/python2.7/site-packages/rest_framework/serializers.py" in data
      674.         ret = super(ListSerializer, self).data
    
    File "/home/prime/.virtualenvs/omapi/local/lib/python2.7/site-packages/rest_framework/serializers.py" in data
      239.                 self._data = self.to_representation(self.instance)
    
    File "/home/prime/.virtualenvs/omapi/local/lib/python2.7/site-packages/rest_framework/serializers.py" in to_representation
      614.             self.child.to_representation(item) for item in iterable
    
    File "/home/prime/.virtualenvs/omapi/local/lib/python2.7/site-packages/rest_framework/serializers.py" in to_representation
      472.                 ret[field.field_name] = field.to_representation(attribute)
    
    File "/home/prime/.virtualenvs/omapi/local/lib/python2.7/site-packages/rest_framework/serializers.py" in to_representation
      614.             self.child.to_representation(item) for item in iterable
    
    File "/home/prime/.virtualenvs/omapi/local/lib/python2.7/site-packages/rest_framework/serializers.py" in to_representation
      472.                 ret[field.field_name] = field.to_representation(attribute)
    
    File "/home/prime/.virtualenvs/omapi/local/lib/python2.7/site-packages/rest_framework/serializers.py" in to_representation
      614.             self.child.to_representation(item) for item in iterable
    
    Exception Type: TypeError at /v1/students/
    Exception Value: 'Guardian' object is not iterable
    

How do I save `Student instance` with `Guardian` and `Relation`.How can I
achieve this I know a custom create method is required but how do I by pass
this error. Or is there any other way to `serialize and deserialize` this kind
of relation.


Answer: You'll need to have the `MembershipSerializer` nested in the `GroupSerializer`
replacing the `PersonSerializer` and have the `MembershipSerializer` that has
a nested `PersonSerializer` in order for this to work.

Alternatively, you could replace the `PersonSerializer` with a regular
`Serializer` and get the dataset explicitly by yourself instead of relying on
automated DRF.

Edit following the question edition:

    
    
    class RelationSerializer(serializers.ModelSerializer):
        guardian = GuardianSerializer(many=True)
    

Since the relation between `Relation` and `Guardian` is a `ForeignKey` you
need to remove the `many=True` here.

