DRF SlugRelatedField вызывает дополнительные запросы с аргументом `queryset` при выполнении get запроса
В отладочной панели инструментов я могу сказать, что есть дублирующие запросы, указывающие на source
и target
, а также workflow
, которые являются внешними ключами моей модели Flow. А в сериализаторе я использую SlugRelatedField для создания с аргументом queryset
.
Поэтому я решил сделать эти два поля read_only=True
и убрать аргумент queryset
. И все прекрасно работает.
мой код выглядит так:
# 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 может вызвать дублирование запросов. Любая помощь будет принята с благодарностью.