Представьте, что у аутентифицированного пользователя при открытии страниц постоянно выполняются какие-то запросы, например, подгружается дополнительный список уведомлений, а также его профиль. И используем эту информацию в шаблонах, например вот так.
- {% 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',
- )