Почему Django генерирует дополнительные запросы для связанных полей?
Я использую drf и django-debug-toolbar.
# model
class Item(models.Model):
title = models.CharField(max_length=255)
description = models.TextField()
owner = models.ForeignKey(User, on_delete=models.CASCADE)
# serializer
class ItemSerializer(serializers.ModelSerializer):
class Meta:
model = Item
fields = ["id", "title", "description", "owner"]
view
class ItemViewSet(ModelViewSet): queryset = Item.objects.all()
serializer_class = ItemSerializer
И я заметил дополнительный запрос, который генерируется, и я не знаю почему.
SELECT "marketplace_user"."id",
"marketplace_user"."password",
"marketplace_user"."last_login",
"marketplace_user"."is_superuser",
"marketplace_user"."first_name",
"marketplace_user"."last_name",
"marketplace_user"."is_staff",
"marketplace_user"."is_active",
"marketplace_user"."date_joined",
"marketplace_user"."email"
FROM "marketplace_user"
LIMIT 1000
Может ли кто-нибудь помочь мне разобраться в этом?
Чтобы избежать лишних запросов при обращении к связанным полям в Django, вы можете использовать prefetch_related
. Этот метод помогает оптимизировать доступ к базе данных, получая связанные объекты в одном запросе вместо отдельных запросов для каждого отношения.
За более подробной информацией о том, как использовать prefetch_related
, вы можете обратиться к официальной документации Django: Django prefetch_related
.
Это выглядит так, как будто этого не должно было случиться.
- Используете ли вы сигналы по отношению к модели
Item
? - Или у вас есть
depth=1
на сериализаторе? - Или ваше представление (или сериализатор) каким-либо образом вызывает
item.owner
?
Все это объясняет, почему генерируется этот дополнительный запрос.
Используйте .select_related(…)
[Django-doc] для получения данных owner
в том же запросе:
class ItemViewSet(ModelViewSet):
queryset = Item.objects.select_related('owner')
serializer_class = ItemSerializer
Если же это форма, которую Django генерирует при посещении HTML-формы, то она предназначена для заполнения выпадающего списка, это не часть логики самого API.