Imagine that for an authenticated user, when opening pages, some requests are constantly being executed, for example, an additional list of notifications is loaded, as well as his profile. And we use this information in templates, for example this way.
{% if user.is_authenticated %} {{ user.profile.avatar }} {{ user.notices.count }} {% endif %}
Both profile and notices are data models for which a query to the database is required, and each query is an additional connection and additional data retrieval, which increases the response time of the site. At the same time, Django uses the mechanism of sampling the corresponding models in a single database query to speed up the selections.
It turns out that the three initial queries can be combined into one query. But if everything is more or less clear with ordinary models, then a problem arises with the authenticated user’s object, since at first glance it is not clear when and where user data is taken.
Answer: An authenticated user gets into the authentication backend.
Therefore, we need to write our own authentication backend so that we can execute select and prefetch requests when searching for a user.
It will look as follows.
# -*- 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
And for this to work, you need to add our authentication backend in the settings.
AUTHENTICATION_BACKENDS = ( 'my_app.backends.MyBackend', 'django.contrib.auth.backends.ModelBackend', )