Django’s auth module
django.contrib.auth is created so that
additional project specific data is appended to the User model
by using OneToOneField in some other model pointing to the User
model. I wanted to have
MyUser accessible as
It is possible to create a middleware which replaces the user object after Django has populated it. This works, but it is wrong as the default User object has been used first and then replaced with something else.
This is the User model I would like to use:
class MyUser(models.Model): class Meta: proxy = True
It is an empty proxy for this example. The user object can be pretty much whatever you want.
Django’s auth module has a way to use different auth backends. All user object related operations are handled in the backend and we can change the backend. Sounds nice.
class MyAuthBackend(ModelBackend): def authenticate(**credentials): return super(MyAuthBackend, self).authenticate(**credentials) def get_user(self, user_id): try: return MyUser.objects.get(id=user_id) except MyUser.DoesNotExist: return None
This auth backend is then enabled in the settings.py file:
AUTHENTICATION_BACKENDS = ( 'myauth.MyAuthBackend', )
Now we’ve achieved the goal. Django’s auth system has
request.user with our MyUser instance.
If you are creating reusable Django app then you should
always remember to get the User object from
django.contrib.auth.get_user(user_id) if you want to have
access to other than the current user in
There are downsides in this. One of the biggest being that your user model should always be a proxy for the Djangos user model if you want to enable compatibility with other apps.