As part of developing Hawgrade, I’m learning the Django framework. That seemed like a noble idea about a week ago, and I’m practically competent already, but I have run into several snags so far. Major snags. Hair-pulling snags. One of the big ones was how to create a profile while simultaneously registering a user with django-registration 1.0 (FYI: I am using Python 2.7.4 with Django 1.5.1 on Ubuntu 13.04 “Raring Ringtail” x86). I’ve decided to do this post because I saw about a million questions about this topic on StackOverflow. This tutorial assumes that you have already installed django-registration and have included it in your urls.py file such that you access the django-registration app in your accounts/ url:
urlpatterns = patterns('', # ... url(r'^accounts/', include('registration.backends.default.urls')), # ... )
We’re going to do the following:
- Define a model for our profile.
- Define a registration form that inherits from registration.forms.RegistrationForm.
- Attach to the django-registration user_registered signal so we know when the user registers. We save the user’s profile in the callback.
- Modify urls.py to use our custom registration view.
And now, we get to the Python! We’ll start in models.py. Our example profile stores whether or not a user is human.
class ExUserProfile(models.Model): user = models.ForeignKey(User, unique=True) is_human = models.BooleanField() def __unicode__(self): return self.user
Next, we need the custom registration form. If you don’t already have a file named forms.py in your app, make one. You’re going to make a custom form.
from registration.forms import RegistrationForm from django import forms class ExRegistrationForm(RegistrationForm): is_human = forms.ChoiceField(label = "Are you human?:")
After the form, we need to attach to the user_registered signal. This is easily accomplished. We’re going to put the method in our models.py file, because, well…I’m new to this…the Django documentation says so!
from registration.signals import user_registered def user_registered_callback(sender, user, request, **kwargs): profile = ExUserProfile(user = user) profile.is_human = bool(request.POST["is_human"]) profile.save() user_registered.connect(user_registered_callback)
The last step is the simplest one: editing the urls in urls.py so that users can actually access your cool new registration form. It is REALLY IMPORTANT to put your new entry BEFORE the django-registration include entry.
from YOUR_APP.forms import ExRegistrationForm from registration.backends.default.views import RegistrationView urlpatterns = patterns('', # ... url(r'accounts/register/$', RegistrationView.as_view(form_class = ExRegistrationForm), name = 'registration_register'), url(r'^accounts/', include('registration.backends.default.urls')), # ... )
This code should be fairly extensible–even if you’re not very familiar with Django. One thing I have noticed is that the documentation is very thorough. Good luck!