Представьте, что у аутентифицированного пользователя при открытии страниц постоянно выполняются какие-то запросы, например, подгружается дополнительный список уведомлений, а также его профиль. И используем эту информацию в шаблонах, например вот так.
{% if user.is_authenticated %} {{ user.profile.avatar }} {{ user.notices.count }} {% endif %}
И профиль, и уведомления — это модели данных, для которых требуется запрос к базе данных, а каждый запрос — это дополнительное подключение и дополнительное получение данных, что увеличивает время отклика сайта. В то же время Django использует механизм выборки соответствующих моделей в одном запросе к базе данных для ускорения выборки.
Получается, что три исходных запроса можно объединить в один запрос. Но если с обычными моделями все более-менее понятно, то с аутентифицированным объектом пользователя возникает проблема, так как на первый взгляд непонятно, когда и откуда берутся пользовательские данные.
Ответ: Аутентифицированный пользователь попадает в серверную часть аутентификации.
Поэтому нам нужно написать собственный сервер аутентификации, чтобы мы могли выполнять запросы на выборку и предварительную выборку при поиске пользователя.
Это будет выглядеть следующим образом.
# -*- coding: utf-8 -*- from django.contrib.auth import get_user_model class MyBackend: def get_user(self, user_id): try: return get_user_model().objects.select_related('profile').prefetch_related('notices').get(pk=user_id) except get_user_model().DoesNotExist: return None
И чтобы это работало, вам нужно добавить наш бэкенд аутентификации в настройках.
AUTHENTICATION_BACKENDS = ( 'my_app.backends.MyBackend', 'django.contrib.auth.backends.ModelBackend', )