UPDATE 2020-01-02
⚠ The following answer was never updated to the latest Python and Django versions. Since writing this a few years ago packages have been released to solve this problem. Nowadays I highly recommend usingdjango-crum
which implements the same technique but has tests and is updated regularly: https://pypi.org/project/django-crum/
The least obstrusive way is to use a CurrentUserMiddleware
to store the current user in a thread local object:
current_user.py
from threading import local
_user = local()
class CurrentUserMiddleware(object):
def process_request(self, request):
_user.value = request.user
def get_current_user():
return _user.value
Now you only need to add this middleware to your MIDDLEWARE_CLASSES after the authentication middleware.
settings.py
MIDDLEWARE_CLASSES = (
...
'django.contrib.auth.middleware.AuthenticationMiddleware',
...
'current_user.CurrentUserMiddleware',
...
)
Your model can now use the get_current_user
function to access the user without having to pass the request object around.
models.py
from django.db import models
from current_user import get_current_user
class MyModel(models.Model):
created_by = models.ForeignKey('auth.User', default=get_current_user)
Hint:
If you are using Django CMS you do not even need to define your own CurrentUserMiddleware but can use cms.middleware.user.CurrentUserMiddleware
and the cms.utils.permissions.get_current_user
function to retrieve the current user.