获取关系数据的有效方法

问题描述 投票:0回答:1

我有一个 Modal ABC 和一个名为 GROUP 的字段,它是一个外键,并且这个模型 Abc 也在另一个模型 XYZ 中用作外键。

我的要求是,当我使用(whse =“01”和abc =“02”)等过滤器查看XYZ列表时,我想获取组的名称(来自模型abc)以及该组的列表数据XYZ 模型。

class ABC(models.Model):
    group = models.ForeignKey(Group, on_delete=models.CASCADE)


class XYZ(models.Model):
    abc = models.ForeignKey(ABC, on_delete=models.CASCADE)
    whse = models.ForeignKey(WHSE, on_delete=models.CASCADE)
    qty = models.CharField()

我现在所做的是 - 在序列化器中定义一个 SerializerMethodField() 字段。

这是代码-

class XYZSerializer(serializers.ModelSerializer):
    groupName = serializers.SerializerMethodField()

    def get_groupName(self, instance):
        return instance.abc.group.name if instance.abc else ''

    class Meta:
        model = ZYX
        fields = '__all__'

我得到了我想要的结果,但您可以看到我的过滤器要求始终在 XYZ 模型上(whse =“01”和 abc =“02”),因此 get_groupName 的值对于我的每个请求(我的 abc 在输出列表中始终相同,因此组名称也相同)。

如何格式化我的数据、序列化器以减少每个列表项的数据库查询(以查找组名称)?

编辑- 编辑-

这是我的观点

class XYZ_View(generics.ListAPIView):
    permission_classes = [IsAuthenticated]
    serializer_class = XYZSerializer

    def get_queryset(self):
        abcId = self.request.GET.get('abc')
        whseId = self.request.GET.get('whse')
        if abcId and whseId is not None:
            qs = ZYX.objects.filter(abc = itemId, whse = whseId)
            return qs
        return ZYX.objects.none()
django django-rest-framework
1个回答
0
投票

您可以使用

Group
 
[Django-doc]
: 获取
.select_related(…)

class XYZ_View(generics.ListAPIView):
    permission_classes = [IsAuthenticated]
    serializer_class = XYZSerializer

    def get_queryset(self):
        abcId = self.request.GET.get('abc')
        whseId = self.request.GET.get('whse')
        if abcId and whseId is not None:
            return XYZ.objects.filter(abc=itemId, whse=whseId).select_related(
                'abc__group'
            )
        return XYZ.objects.none()

您可以将序列化器重写为:

class XYZSerializer(serializers.ModelSerializer):
    groupName = serializers.CharField(read_only=True, source='abc.group.name')

    class Meta:
        model = XYZ
        fields = '__all__'
© www.soinside.com 2019 - 2025. All rights reserved.