Почему 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.

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