Extending the User Model

This example is based on an outdated version of Django and will no longer work with the current development version at all due to changes in subclassing and the removal of the 'replaces_module' option. A separate way of dealing with this problem which works in both older and current versions of Django is detailed here: http://www.b-list.org/weblog/2006/06/06/django-tips-extending-user-model

Also look at the DjangoBook chapter 12: http://www.djangobook.com/en/beta/chapter12/ for more information about extending the User Model in current versions.

On the Django IRC channel, I was helped through some resources for replacing the auth systems's User model with my own extended version. Here are the notes I made. Note that it was 2:30 am local time, beware hacker fatigue syndrome.

[02:18] <harmless> phew, that was NOT easy
[02:18] <harmless> note to all:
[02:18] <harmless> if you wish to replace the auth User model with an extended version, you must do the following:
[02:19] <harmless> 1. patch the createsuperuser function in core/management.py to catch ObjectDoesNotExist rather than users.UserDoesNotExist
[02:20] <harmless> 2. ensure that your model's META specifies module_name = "users"
[02:21] <harmless> 3. provide a _module_create_user function that does all of what django.models.auth.User's does, plus inits your new fields
[02:21] <harmless> 3 a. note that it's easier to use keyword arguments here, as it's not clear what the field order is when extending a model
[02:21] <harmless> 4. wipe your entire database every time you make a change.
[02:22] <harmless> and that pretty much did it for me, i've got my own user class being used successfully for auth and admin, and it's a single nice class in the admin interface.
[02:22] <harmless> so maybe next time i need to do this, this transcript will be a quick google search away :)
[02:25] <alect> perhaps you should wikify it
[02:35] <paulproteus|lapt> I'm with alect on this one. (-:
[02:36] <harmless> well, i'm not sure it's wikiworthy at this point
[02:36] <harmless> it looks like it's changing right away anyways
[02:36] <harmless> but i'll paste it in with a "late night hacking" warning

Missing here is step 2b, ensure that your model's META specified replaces_module="auth.users", and step 5, you must copy the original models' entire META.admin section if you wish to change it at all.

Here's what my model looks like at this point:

class User(users.User):    
  gamename = meta.CharField("Game Name", maxlength=100, blank=True)
  url = meta.CharField(maxlength=100, blank=True)
  description = meta.TextField(blank=True)   
  # SNIP a few more extra model attributes

  class META:    
    replaces_module = 'auth.users'
    module_name = "users"
    verbose_name = _('User')
    verbose_name_plural = _('Users')
    module_constants = {
      'SESSION_KEY': '_auth_user_id',
    }
    ordering = ('username',)
    exceptions = ('SiteProfileNotAvailable',)
   
    admin = meta.Admin(
      fields = (
        (None, {'fields': ('username', 'password_md5')}),
        (_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
        (_('Extended info'), {'fields': ('gamename', 'url', 'description')}),
        (_('Permissions'), {'fields': ('is_staff', 'is_active', 'is_superuser', 'user_permissions')}),
        (_('Important dates'), {'fields': ('last_login', 'date_joined')}),
        (_('Groups'), {'fields': ('groups',)}),
      ),
      list_display = ('username', 'gamename', 'first_name', 'last_name', 'is_staff'),
      list_filter = ('is_staff', 'is_superuser'),
      search_fields = ('username', 'first_name', 'last_name', 'email', 
                       'gamename', 'description'),
    )


NOTE

If you're using development django, these steps change a bit.

  • you won't need to modify createsuperuser (step 1 above)
  • you will need to change password_md5 above to just password anywhere it appears in your model's META - specifically, in admin.fields

Comments

  • How does this work in the magic-removal branch?
  • Apparently the modern version of django.contrib.auth can assign a model to get_profile for attatching extra data to a User.
Last modified 9 years ago Last modified on 02/20/2007 06:07:21 PM

Attachments (1)

Download all attachments as: .zip

Back to Top