Использование select_related в данном случае в django rest?

У меня есть ситуация, в которой я не уверен, буду ли я использовать select_related или нет. У меня есть модель следующего вида:

class Example(models.Model): 

    title = models.CharField(max_length=255, blank=True)  
    message = models.TextField(blank=True)
    user = models.ForeignKey(
    User,
    on_delete=models.CASCADE,
    null=True,
    related_name="user_example",
)
    /................./

Теперь в моем представлении я использую логику фильтрации следующим образом:

def get_queryset(self):
    
    search = self.request.query_params.get("search", None)

    if search_query is not None:
        queryset = Reactions.objects.filter(
            Q(user__name__icontains=search)
            | Q(user__email__icontains=search)                
        ).distinct()

В данном примере модель имеет fk-отношение с User, поэтому это прямое отношение, а не обратное. Должен ли я применять .select_related('user').filter(...) в этом примере выше, чтобы уменьшить количество запросов или здесь нет необходимости... Я не могу понять это.

Serizalizer:

class ExampleSerializer(serializers.ModelSerializer):

    user = UserSerializer()

    class Meta:
        model = Reactions
        fields = ["id", "user", "title", "message"]

Да, вы должны. Из docs:

select_related работает путем создания SQL-соединения и включения полей связанного объекта в оператор SELECT. По этой причине select_related получает связанные объекты в одном запросе к базе данных. Однако, чтобы избежать гораздо большего набора результатов, который получился бы в результате объединения через "многие" отношения, select_related ограничен однозначными отношениями - внешний ключ и один-к-одному.

prefetch_related, с другой стороны, выполняет отдельный поиск для каждого отношения и выполняет "объединение" в Python...

В вашем случае мы имеем дело с ForeignKey, поэтому подходит select_related. Если вы хотите убедиться, что это уменьшает количество запросов к БД, то для этого можно установить django-debug-toolbar.

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