DRF多对一反向查询 [英] DRF many-to-one reverse lookup

查看:263
本文介绍了DRF多对一反向查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆