Эффективный способ получения данных о взаимоотношениях

У меня есть модель ABC и поле с именем GROUP, которое является внешним ключом, и эта модель Abc также используется в качестве внешнего ключа в другой модели XYZ.

Мое требование заключается в том, что при просмотре списка XYZ с фильтрами типа (whse=«01» и abc=«02») я хочу получить название группы (из модели 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__'

Я получаю желаемый результат, но вы видите, что мое требование фильтра всегда (whse=«01» и abc=«02») на модели XYZ, и поэтому значение get_groupName всегда будет оставаться одинаковым для каждого моего запроса (мой abc всегда будет одинаковым в выходном списке, поэтому будет и имя группы).

Как я могу отформатировать свои данные, сериализатор, чтобы уменьшить запрос к базе данных, (чтобы найти groupName) для каждого элемента списка?

EDIT - EDIT -

вот мой взгляд

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()

Вы получаете Group вместе с ним .select_related(…) [Django-doc]:

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__'
Вернуться на верх