Saturday, May 17, 2008

Extending the user model: profiles in Django

(permalink)
I think the documentation about using profiles & the get_profile() function isn't as clear and/or elegant as it could be. The problem with django's recommended implementation of profiles is that when a user is created, a user's profile isn't automatically created - it's not part of the same model. Managing the two can be tricky - if you mess up, you're bound to get ObjectDoesNotExist errors.

My solution was to never use get_profiles() directly - but instead add a helper method where any ObjectDoesNotExist errors are caught and resolved:


First, create a profile class in models.py:
from django.db import models
from django.contrib.auth.models import User

class UserProfile(models.Model):
    karma = models.IntegerField(default=1, core=True)
    url = models.URLField(default="", core=True)
    user = models.ForeignKey(User, unique=True)

Note, if you want to be able to create profiles using the Django admin interface, change the last line to the following:
user = models.ForeignKey(User, unique=True, edit_inline=models.TABULAR, num_in_admin=1,min_num_in_admin=1, max_num_in_admin=1,num_extra_on_change=0)


Add this line to settings.py:
AUTH_PROFILE_MODULE = 'core.UserProfile'

(change your line to 'appname.ModelName' - note, do NOT include your project name or anything else. Just your application name and model name (the model name is UserProfile, unless you change it).

Finally, add to views.py:
from django.contrib.auth.models import User
from project.core.models import UserProfile
from django.core.exceptions import ObjectDoesNotExist

def get_or_create_profile(user):
    try:
        profile = user.get_profile()
        except ObjectDoesNotExist:
        #create profile - CUSTOMIZE THIS LINE TO OYUR MODEL:
        profile = UserProfile(karma='1', url='http://example.org', user=user)
        profile.save()
    return profile


Now, in views.py, to access a user's profile, you only need two lines:
user = User.objects.get(pk = user_id)
user.userprofile = get_or_create_profile(user)


And, say if you wanted to change a value:
user.userprofile.karma += 1
user.userprofile.save()


Easy, eh?

Labels: , ,

blog comments powered by Disqus

Links to this post:

Create a Link

<< Home