在Django REST Framework中使用直通模型序列化ManyToManyFields [英] Serialize ManyToManyFields with a Through Model in Django REST Framework
本文介绍了在Django REST Framework中使用直通模型序列化ManyToManyFields的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我与通过
模型的这种M2M关系为
I have this M2M relation with through
model as
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)
请注意,直通模型中有 date_joined
和 invite_reason
额外的字段.
Please note that, I have extra fields date_joined
and invite_reason
in the through model.
现在,我想使用DRF序列化 Group
查询集,因此我选择了以下序列化程序设置.
Now, I want to serialize the Group
queryset using DRF and thus I choose the below serializer setup.
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__"
,它返回以下响应,
[
{
"id": 1,
"members": [
{
"id": 1,
"name": "Jerin"
}
],
"name": "Developer"
},
{
"id": 2,
"members": [
{
"id": 1,
"name": "Jerin"
}
],
"name": "Team Lead"
}
]
在此, 成员
字段返回 Person
信息,这很完美.
Here, the members
field returning the Person
information, which is perfect.
但是
如何将 date_joined
和 invite_reason
字段/信息添加到JSON响应的 members
字段中?>
How can I add the date_joined
and invite_reason
field/info into the members
field of the JSON response?
推荐答案
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__"
注意:
- 覆盖
PersonSerializer
的to_representation(...)
方法,以将多余的数据注入到成员字段 - 我们需要
person
实例/pk和group
实例/pk来标识要序列化的Membership
实例.为此,我们使用了 serializer上下文传递基本数据
- Override the
to_representation(...)
method ofPersonSerializer
to inject extra data into themembers
field of the JSON - We need
person
instance/pk andgroup
instance/pk to identify theMembership
instance to be serialized. For that, we have used the serializer context to pass essential data
这篇关于在Django REST Framework中使用直通模型序列化ManyToManyFields的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文