Reputation: 21
I'd like to extend the User model, so I can put in some extra fields and functions (not only fields, keep in mind, or else (well, still) I could use get_profile(), which I think is ugly).
Also I would like to use that new extended User model in request.user, like this:
Extended User model:
# imports etc
class CustomUser(User):
extra_field = ...
def extra_function(self):
...
return ...
Example usage view:
# imports etc
def extra_function_view(request):
print request.user.username
print request.user.extra_field
request.user.extra_function()
return HttpResponse( ... )
The above code obviously doesn't work, because extra_field and extra_function are not in the User model.
Now I found a method to accomplish this, using an authentication backend, which is kinda complex, and which I couldn't get to work in Django 1.2.3.
AUTHENTICATION_BACKENDS = (
'myproject.auth_backends.CustomUserModelBackend',
)
...
CUSTOM_USER_MODEL = 'accounts.CustomUser'
Further more tried some other methods, like using signals, which didn't work. To me, the only solution seems to adjust the User model within Django (which isn't an elegant solution, adjusting Django's source code, but is code-wise a neat solution).
So I'm looking for a solution for this.. has anyone done this before?
Thanks for now
Stefan
Upvotes: 1
Views: 1543
Reputation: 1659
You're on the right track with adjusting the Authentication Backend.
Authentication backends can be pretty simple, here is a snip of ours we use in our project.
class LocalAccount(object):
def authenticate(self, system=None, username=None, password=None):
try:
user = User.objects.get(system=system, alias=username)
if user.check_password(password):
return user
except User.DoesNotExist:
return None
def get_user(self, user_id):
'returns user'
def get_all_permissions(self, user_obj):
'returns user permissions'
def has_perm(self, user_obj, perm):
'verifies permission, remember you can hardcode these'
def get_group_permissions(self, user_obj):
return set() #We don't use this
def has_module_perms(self, user_obj, app_label):
return False
This allows you to return whatever user model you wish to return. As long as your user model is basically like Django's user model you won't run into any issues.
Also keep in mind that extending user and including the application will cause both the Django User model and your own User model to be in the database with model inheritance. Your best option is to copy the Django User model and alter it. For our project we don't even include 'auth' in the installed apps setting.
The concept here is Python duck typing. As long as the User model that you create has the same interface that Django is looking for (methods, fields) it doesn't matter if it's actually the User class it specified.
Upvotes: 2