If we use Django's AuthenticationMiddleware
[Django-doc],
then the HttpRequest
s that are passed to
the view have an attribute .user
that we
can use to obtain the logged in user, or the
AnonymousUser
in case there is no logged in
user for that request.
Often people make queries to obtain the user object, for example with:
from django.contrib.auth.models import User
def my_view(request):
user = User.objects.get(username=request.user)
# …
Why is it a problem?
It is unnecessary. The
request.user
is a user model
object. It thus has all the attributes the user model
has. By querying the database for the user with the
given username, we make an extra query, so now we query
twice to obtain user details instead of once.
Another problem with this is that we make the views
less flexible. Indeed, we here import the user
model, if we later decide to use another user model,
then we need to rewrite the views. If we would use get_user_model(…)
then it is still not very flexible, since we here make
the assumption that the user model will have a
username
, and that calling
str(…)
on the user model will return that
username. If we thus would migrate to a user model that
has only an email address, then we will still have to
update the views.
What can be done to resolve the problem?
Use request.user
[Django-doc]
directly. This is an object of the actively used user
model, so Django's User
model by default.
It means we do not have to worry about the user model,
or how it is linked to the session.
def my_view(request):
user = request.user
# …
Extra tips
It is possible that sometimes we want to update the
user model with the values stored in the database. Using
an explicit query however is not very flexible for the
reasons explained above. In that case we can use the .refresh_from_db(…)
method [Django-doc] to refresh the data
in the request.user
object with values from
the database:
def my_view(request):
user = request.user
# …
# we want to retrieve the (updated) values from the database
user.refresh_from_db()
# …