Evgenii Legotckoi
26 августа 2019 г. 13:51

Django - Урок 047. Как сделать select_related и prefetch_related для аутентифицированного пользователя

Представьте, что у аутентифицированного пользователя при открытии страниц постоянно выполняются какие-то запросы, например, подгружается дополнительный список уведомлений, а также его профиль. И используем эту информацию в шаблонах, например вот так.

  1. {% if user.is_authenticated %}
  2. {{ user.profile.avatar }}
  3. {{ user.notices.count }}
  4. {% endif %}

И профиль, и уведомления — это модели данных, для которых требуется запрос к базе данных, а каждый запрос — это дополнительное подключение и дополнительное получение данных, что увеличивает время отклика сайта. В то же время Django использует механизм выборки соответствующих моделей в одном запросе к базе данных для ускорения выборки.

Получается, что три исходных запроса можно объединить в один запрос. Но если с обычными моделями все более-менее понятно, то с аутентифицированным объектом пользователя возникает проблема, так как на первый взгляд непонятно, когда и откуда берутся пользовательские данные.

Ответ: Аутентифицированный пользователь попадает в серверную часть аутентификации.

Поэтому нам нужно написать собственный сервер аутентификации, чтобы мы могли выполнять запросы на выборку и предварительную выборку при поиске пользователя.

Это будет выглядеть следующим образом.

  1. # -*- coding: utf-8 -*-
  2.  
  3. from django.contrib.auth import get_user_model
  4.  
  5.  
  6. class MyBackend:
  7.  
  8. def get_user(self, user_id):
  9. try:
  10. return get_user_model().objects.select_related('profile').prefetch_related('notices').get(pk=user_id)
  11. except get_user_model().DoesNotExist:
  12. return None
  13.  

И чтобы это работало, вам нужно добавить наш бэкенд аутентификации в настройках.

  1. AUTHENTICATION_BACKENDS = (
  2. 'my_app.backends.MyBackend',
  3. 'django.contrib.auth.backends.ModelBackend',
  4. )

Вам это нравится? Поделитесь в социальных сетях!

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь