DRF多对一反向查询 [英] DRF many-to-one reverse lookup
问题描述
我有一个API端点,可以返回宠物及其主人.
I have an API endpoint returning pets and their owners.
- 每个所有者都有一个名字,并一个或多个宠物
- 每只宠物都有一个名字,一个拥有者
示例Django模型:
Example Django models:
class Owner(models.Model):
name = models.CharField(max_length=200)
class Pet(models.Model):
owner = models.ForeignKey(Owner, on_delete=models.CASCADE)
name = models.CharField(max_length=200)
我已将我的API配置为返回JSON数据,如下所示:
I've configured my API to return JSON data like this:
[
{
"id": 2,
"name": "Scotch",
"owner": {
"id": 2,
"name": "Ben"
}
},
{
"id": 3,
"name": "Fluffy",
"owner": {
"id": 1,
"name": "Fred"
}
},
{
"id": 1,
"name": "Spot",
"owner": {
"id": 1,
"name": "Fred"
}
}
]
DRF序列化器示例:
Example DRF serializers:
class OwnerSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Owner
fields = ("id", "name")
class PetSerializer(serializers.HyperlinkedModelSerializer):
owner = OwnerSerializer()
class Meta:
model = Pet
fields = ("id", "name", "owner")
虽然一切都很好,但我实际上想要一个可以返回所有者及其宠物列表的终结点.因此,我将改为获取此数据:
While that's all fine and dandy, I'd actually like to have an endpoint that returns a list of owners and their pets. So I'd get this data instead:
[
{
"id": 1,
"name": "Fred",
"pets": [
{ "id": 1, "name": "Spot" },
{ "id": 3, "name": "Fluffy" }
]
},
{
"id": 2,
"name": "Ben",
"pets": [
{ "id": 2, "name": "Scotch" }
]
}
]
如何获得该输出?
推荐答案
您需要像这样将 pet_set
字段添加到OwnerSerializer:
You need to add pet_set
field to OwnerSerializer like this:
class PetSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Pet
fields = ("id", "name")
class OwnerSerializer(serializers.HyperlinkedModelSerializer):
pet_set = PetSerializer(many=True, read_only=True)
class Meta:
model = Owner
fields = ("id", "name", "pet_set")
这将起作用,因为在您的情况下,多对一关系默认反向查找名称是< model> _set
或 pet_set
.您可以使用 related_name
:
This will work bacause many-to-one relation default reverse lookup name is <model>_set
or pet_set
in your case. You can change it by using related_name
:
class Pet(models.Model):
owner = models.ForeignKey(Owner, related_name='pets', on_delete=models.CASCADE)
在这种情况下,您可以在序列化程序中使用 pets
名称:
In this case you can use pets
name inside serializer:
class OwnerSerializer(serializers.HyperlinkedModelSerializer):
pets = PetSerializer(many=True, read_only=True)
现在在 OwnerListView
中,您可以使用此新的序列化器:
Now in OwnerListView
you can use this new serializer:
class OwnerListView(ListAPIView):
queryset = Owner.objects.all()
serializer_class = OwnerSerializer
这篇关于DRF多对一反向查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!