Reputation: 5507
I want to save m2m relationship with through model
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
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.
Upvotes: 0
Views: 1178
Reputation: 20986
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.
Upvotes: 1
Reputation: 1015
class MembershipSerializer(serializers.ModelSerializer):
person = serializers.PrimaryKeyRelatedField(queryset=Person.objects.all())
group = serializers.PrimaryKeyRelatedField(queryset=Group.objects.all())
class Meta:
model = Membership
fields = ('person', 'group', 'date_joined', 'invite_reason')
class PersonSerializer(serializers.ModelSerializer):
class Meta:
fields = ('name')
class GroupSerializer(serializers.ModelSerializer):
class Meta:
model = Group
fields = ('name')
Hope the answer helps :)
Upvotes: 1