python|DRF 多对一反向查找 序列化

参考链接
导读
本文主要看序列化
以下公式二选一:
从表属性写 主表s属性 = 主表serializers()
主表属性写 从表_set = 从表serializers(many=True, read_only=True)
主表 主人 owner
从表 宠物 pet
我有一个API端点返回宠物及其主人。
每位所有者都有一个名称,一个或多个宠物
每只宠物都有一个名字,一个所有者
示例Django模型:

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数据,如下所示:
[ { "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序列化程序:
```python 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")

虽然这一切都很精致,但我真的希望有一个能够返回所有者及其宠物列表的端点。所以我得到了这些数据:
[ { "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,如下所示:
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")

【python|DRF 多对一反向查找 序列化】这将有效,因为在您的情况下,多对一关系默认反向查找名称为_setpet_set。您可以使用related_name:
进行更改
class Pet(models.Model): owner = models.ForeignKey(Owner, related_name='pets', on_delete=models.CASCADE)

在这种情况下,您可以在序列化程序中使用pets名称:
class OwnerSerializer(serializers.HyperlinkedModelSerializer): pets = PetSerializer(many=True, read_only=True)

现在在OwnerListView中,您可以使用这个新的序列化程序:
class OwnerListView(ListAPIView): queryset = Owner.objects.all() serializer_class = OwnerSerializer

更改/添加 serializer.py ,如下所示
class PetSerializer(serializers.ModelSerializer): class Meta: model = Pet fields = ("id", "name")class OwnerNewSerializer(serializers.ModelSerializer): pets = PetSerializer(many=True, source='pet_set')class Meta: model = Owner fields = ('id', 'name', 'pets')

views.py
class OwnerAPI(viewsets.ModelViewSet): queryset = Owner.objects.all() serializer_class = OwnerNewSerialize

    推荐阅读