[英]Serialize ManyToManyFields with a Through Model in Django REST Framework
I have this M2M relation with through
model as我through
model 与此 M2M 关系为
class Person(models.Model):
name = models.CharField(max_length=128)
def __str__(self):
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
def __str__(self):
return self.name
class Membership(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)
Please note that, I have extra fields date_joined
and invite_reason
in the through model.请注意,我在invite_reason
中有额外的字段date_joined
和邀请原因。
Now, I want to serialize the Group
queryset using DRF and thus I choose the below serializer setup.现在,我想使用 DRF 序列化Group
查询集,因此我选择了下面的序列化程序设置。
class PersonSerializer(serializers.ModelSerializer):
class Meta:
model = Person
fields = "__all__"
class GroupSerializer(serializers.ModelSerializer):
members = PersonSerializer(read_only=True, many=True)
class Meta:
model = Group
fields = "__all__"
and it is returning the following response,它正在返回以下响应,
[
{
"id": 1,
"members": [
{
"id": 1,
"name": "Jerin"
}
],
"name": "Developer"
},
{
"id": 2,
"members": [
{
"id": 1,
"name": "Jerin"
}
],
"name": "Team Lead"
}
]
Here, the members
field returning the Person
information, which is perfect.这里的members
字段返回Person
信息,非常完美。
But,但,
How can I add the date_joined
and invite_reason
field/info into the members
field of the JSON response?如何将date_joined
和invite_reason
字段/信息添加到 JSON 响应的members
字段中?
class PersonSerializer(serializers.ModelSerializer):
class Meta:
model = Person
fields = "__all__"
def serialize_membership(self, person_instance): # simple method to serialize the through model fields membership_instance = person_instance \ .membership_set \ .filter(group=self.context["group_instance"]) \ .first() if membership_instance: return MembershipSerializer(membership_instance).data return {} def to_representation(self, instance): rep = super().to_representation(instance) return {**rep, **self.serialize_membership(instance)}
class MembershipSerializer(serializers.ModelSerializer): # create new serializer to serialize the through model fields class Meta: model = Membership fields = ("date_joined", "invite_reason")
class GroupSerializer(serializers.ModelSerializer):
members = serializers.SerializerMethodField() # use `SerializerMethodField`, can be used to pass context data def get_members(self, group): return PersonSerializer( group.members.all(), many=True, context={"group_instance": group} # should pass this `group` instance as context variable for filtering ).data
class Meta:
model = Group
fields = "__all__"
Notes:笔记:
to_representation(...)
method of PersonSerializer
to inject extra data into the members
field of the JSON覆盖PersonSerializer
的to_representation(...)
方法以将额外数据注入JSON 的members
字段person
instance/pk and group
instance/pk to identify the Membership
instance to be serialized.我们需要person
instance/pk 和group
instance/pk 来识别要序列化的Membership
实例。 For that, we have used the serializer context to pass essential data为此,我们使用了序列化器上下文来传递基本数据
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.