DRF SlugRelatedField вызывает дополнительные запросы с аргументом `queryset` при выполнении get запроса

В отладочной панели инструментов я могу сказать, что есть дублирующие запросы, указывающие на source и target, а также workflow, которые являются внешними ключами моей модели Flow. А в сериализаторе я использую SlugRelatedField для создания с аргументом queryset.

enter image description here

Поэтому я решил сделать эти два поля read_only=True и убрать аргумент queryset. И все прекрасно работает.

enter image description here

мой код выглядит так:

# model

class Activity(models.Model):
    class Meta:
        db_table = "activity"
    uuid = serializers.UUIDField(read_only=True)
    some fields ...


class Flow(models.Model):
    class Meta:
        db_table = "workflow_flow"

    objects = FlowManager()
    source = models.ForeignKey(
        "Activity",
        db_index=True,
        related_name="outgoing",
        to_field='uuid',
        db_constraint=False,
        on_delete=models.CASCADE,
        max_length=32,
        null=True,
        blank=True,
        default=""
    )

    target = models.ForeignKey(
        "Activity",
        db_index=True,
        related_name="incoming",
        to_field='uuid',
        db_constraint=False,
        on_delete=models.CASCADE,
        max_length=32,
        null=True,
        blank=True,
        default=""
    )

    workflow = models.ForeignKey(
        "WorkFlow",
        db_index=True,
        related_name="flows",
        to_field='uuid',
        db_constraint=False,
        on_delete=models.CASCADE,
        max_length=32,
    )
    
# serializer

class FlowSerializer(ModelSerializer):
    class Meta:
        fields = "__all__"
        model = Flow

    condition = serializers.CharField(
        default="",
        required=False,
        allow_null=True,
        allow_blank=True,
        write_only=True
)

    # foreign key
    source = serializers.SlugRelatedField(
        queryset=api_models.Activity.objects.all(),
        slug_field="uuid",
    )

    target = serializers.SlugRelatedField(
        slug_field="uuid",
        queryset=api_models.Activity.objects.all()
    )
    workflow = serializers.SlugRelatedField(slug_field="uuid", queryset=api_models.WorkFlow.objects.all())


# viewset
class FlowViewSet(ModelViewSet):
    queryset = api_models.Flow.objects.all().select_related("source", "target", "workflow").all()
    lookup_field = 'uuid'
    serializer_class = api_serializers.FlowSerializer

Но мне нужно создать эти два поля, есть идеи? Я знаю, что могу изменить их на CharField вместо этого, но мне нужен правильный способ обработки этого.

При чтении исходного кода кверисет SlugRelatedField используется для создания:

    def to_internal_value(self, data):
        queryset = self.get_queryset()
        try:
            return queryset.get(**{self.slug_field: data})
        except ObjectDoesNotExist:
            self.fail('does_not_exist', slug_name=self.slug_field, value=smart_str(data))
        except (TypeError, ValueError):
            self.fail('invalid')

а для представления это так же просто, как:

    def to_representation(self, obj):
        return getattr(obj, self.slug_field)

поэтому я не понимаю, почему запрос get может вызвать дублирование запросов. Любая помощь будет принята с благодарностью.

Вернуться на верх