Django Registration for Newbies

April 13, 2007

introduction
This is another in a series of posts exploring how to build social networking capabilities in a Django application while also exploring related tools and approaches that are new to me. I have been sidetracked for some time now with discussions of REST, and if you’ve been following this series, you’re probably pretty sick of that topic by now. So, lets get back to the application itself.

I recently turned my attention to user account management in Django and what follows are (cleaned-up) notes I made while exploring the django-registration contribution. As a result, this post is very introductory and task oriented, but hopefully, it will help orient newcomers like me to what’s available and provide a foundation for exploring these topics in more depth.

Most sites you build in Django will probably require users to self-register, authenticate and manage their own accounts, and this is certainly a basic requirement of social networking sites. Like any mature Web framework, Django provides robust user management and authentication functionality that, along with some robust add-on code, will allow you to quickly implement common user registration, authentication, and account management approaches while also allowing you to easily customize those approaches for your application’s needs.

Although this post is part of a series, I will try to keep the discussion general, so it shouldn’t assume any knowledge of previous posts.

quickly implementing user registration
Once you’re familiar with Django and the basic documentation on the project’s site, you could do much worse than to look through the posts on James Bennett’s blog, The B-List, which contains many deep insights into Django. One such insightful post, user registration shows how to build a typical registration process in Django. James eventually implemented a newer, more robust version of his approach as a contribution, django-registration, that can easily be installed and used generically in your own application.

The django-registration contribution serves a narrowly defined purpose; from the user’s perspective, it provides two primary functions: account registration and account activation, including the following validations:

  • usernames are checked to ensure uniqueness
  • passwords must be entered twice and match
  • users are asked to accept terms of service

There are two minor prerequisites to using django-registration: you need to use a fairly current version of Django, 0.95 and above that includes the newforms library. If you regularly update Django from Subversion, you should already be running a compatible version. For the default templates to work correctly, you will also need to ensure that django.contrib.humanize is included in your INSTALLED_APPS directive in settings.py, so that it might look like this:

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.humanize',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.admin',
)

The humanize application is part of the Django distribution, like the auth application, and adding it to INSTALLED_APPS is the only step necessary to activate it–you don’t even have to run syncdb. Humanize is a nice application for adding polish to your interface as it massages certain types of numbers into more user friendly formats, such as adding commas to large integers for example.

You will also need the auth, sessions and sites applications indicated above, as well as the SessionMiddleware and AuthenticationMiddleware entries in MIDDLEWARE_CLASSES in settings.py, all of which should already be included in your settings.py by default if you started your application using the django-admin.py startproject command. I also recommend including the admin application in INSTALLED_APPS if you already haven’t, for reasons that will become clear later. Finally, django-registration will need access to an SMTP server to send emails (or you could follow this recipe to use GMail instead).

Complete and up-to-date documentation is provided with the django-registration distribution, but I’m going to try to make the processes of installing and customizing this contribution more explicit for newcomers like me who are still learning their way around Django. Like humanize, django-registration is also a normal Django application, so, for example, it will get checked-out of Subversion and placed alongside any applications in your Django project directory, in a sub-directory called ‘registration’. So, for my ‘tagging_exploration’ django project, I would do this to add the ‘registration’ application at the same level as my ‘tagging’ application:

> cd tagging_exploration
> svn checkout http://django-registration.googlecode.com/svn/trunk/ registration

To activate and configure django-registration, first add it to your INSTALLED_APPS directive in settings.py:

INSTALLED_APPS = (
    'registration',
    'tagging',
    'django.contrib.auth',
    'django.contrib.humanize',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.admin',
)

Then from your Django project directory, install its RegistrationProfile model in the customary way:

> python manage.py syncdb

A few remaining entries in settings.py are needed to control the behavior of django-registration:

ACCOUNT_ACTIVATION_DAYS=7
EMAIL_HOST='localhost'
EMAIL_PORT=1023
EMAIL_HOST_USER='username'
EMAIL_HOST_PASSWORD='password'

Of course, you will have to customize these settings for your environment. ACCOUNT_ACTIVATION_DAYS is an integer representing the number of days in which a user can successfully activate their account.

The django-registration application also sends out emails that contain your site’s URL for the activation link, and that URL is dynamically determined using the ‘sites’ contributed application indicated above. By default, your domain name is listed as ‘example.com’, and the easiest way to change this is to log into the admin application and click on the ‘Sites’ link on the admin home page to get to the relevant entry.

Then, include django-registration’s urls in your project’s urls.py, which for a new project might look like this:

urlpatterns = patterns('',
  (r'^admin/', include('django.contrib.admin.urls')),
  (r'^accounts/', include('registration.urls')),
)

The only thing left to do now is to specify the templates that will be used. You could point to the actual django-registration templates directly by editing the TEMPLATE_DIRS setting in settings.py. For example, this is how I would do it in my project, which has my toy application called ‘tagging’, and uses a little Python trickery to dynamically determine the absolute location of the template directories:

import os
dirname = os.path.dirname(globals()["__file__"])
TEMPLATE_DIRS = (
    os.path.join(dirname, 'tagging/templates'),
    os.path.join(dirname, '../registration/templates'),
)

But ultimately, you will probably want to customize these templates and do so on a per-application basis. So, instead of adding an entry to TEMPLATE_DIRS, copy the registration/templates directory from the django-registration templates directory (that’s registration/templates to be exact) to your application’s templates directory so that in my tagging application, I would have the following template directories off the ‘tagging’ application root:

templates/registration
templates/tagging

Out of the box, the django-registration templates inherit from the base.html template–the template that contains the basic structure of your application’s interface–and override the following blocks:

  • title
  • sidebar
  • content_header
  • content
  • main_content

If you’re starting a new application, you may want to create a very simple base.html template directly under your application’s templates directory to get the basic django-registration templates working so they can then be customized more naturally. Here is a minimal template to get you started:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <style>
      input.required, error {
        border: 2px solid red;
      }
    </style>
    <title>{% block title %}Tagging Exploration{% endblock %}</title>
</head>

<body>
    <div id="sidebar">
        {% block sidebar %}{% endblock %}
    </div>

    <div id="content">
        {% block content %}{% endblock %}
        {% block main_content %}{% endblock %}
    </div>
</body>
</html>

In this bare-bones template, I did add a CSS style to demonstrate that every django-registration form field that is required also has a ‘required’ CSS class defined for it, that you can style accordingly for your site. This CSS class is actually defined in the newforms code in django-registration’s forms.py module.

Conclusion
At this point, django-registration should be properly installed and configured, and you should be able to begin integrating it into your application.

The django-registration application works with Django’s standard user authentication system. So for example, when a user activates an account, the is_active field of the Users object gets updated, indicating the user is allowed to login.

The django-registration application also uses the authentication application’s generic views for login and logout. Other generic views provided by the authentication application that you will likely want to use include those for changing passwords and resetting forgotten passwords. Following the approach taken by the django-registration contribution, we can add these to urls.py, so that the full urls.py now looks something like this:

from django.conf.urls.defaults import *
from django.contrib.auth.views import password_reset, password_reset_done, password_change, password_change_done
from django.views.generic.simple import direct_to_template

urlpatterns = patterns('',
  (r'^admin/', include('django.contrib.admin.urls')),
  (r'^accounts/', include('registration.urls')),
)

urlpatterns += patterns('',
  (r'^accounts/profile/$', direct_to_template, {'template': 'registration/profile.html'}),
  (r'^accounts/password_reset/$', password_reset, {'template_name': 'registration/password_reset.html'}),
  (r'^accounts/password_reset_done/$', password_reset_done, {'template_name': 'registration/password_reset_done.html'}),
  (r'^accounts/password_change/$', password_change, {'template_name': 'registration/password_change.html'}),
  (r'^accounts/password_change_done/$', password_change_done, {'template_name': 'registration/password_change_done.html'}),
)

These views in turn expect to find the following templates, respectively:

  • templates/registration/profile.html
  • templates/registration/password_reset.html
  • templates/registration/password_reset_done.html
  • templates/registration/password_change_done.html
  • templates/registration/password_change_done.html

And the password reset view also expects a template at templates/registration/password_reset_email.html to know how to format the email sent out. (I’ll explain the significance of the profile template momentarily.)

Then, to protect views that require authentication, you can use the login_required decorator as described in the following example from the djangoproject.com user authentication documentation:

from django.contrib.auth.decorators import login_required

@login_required
def my_view(request):
  # pass

This allows the view to be executed normally when the user is logged in, or otherwise automatically redirect to accounts/login, assigning the appropriate absolute URL to the ‘next’ variable as a string and passing it to the login view. (By default, the ‘next’ variable is set to go to accounts/profile in the login view, which I added to urls.py above using the direct_to_template generic view.) You can also access this functionality directly through the redirect_to_login view of the authentication application. Data and methods associated with a logged in user can then be accessed within both view and template code; refer to the User authentication in Django documentation to see what is available.

Hopefully this introduction to django-registration will help you quickly implement this important functionality in your application and orient you to how Django itself manages user accounts and authentication. The django-registration project Web site also has information that can help you troubleshoot specific issues you may experience, and also describes how to clean up user accounts that have not been activated in the allowed time.

In the unlikely event that django-registration can’t be configured to provide the functionality you need, you may want to consult the Django book which describes how to write your own registration process.

resources

previous posts in this series

  1. Implementing Tagging in a Django Application
  2. Toward a RESTful Approach to Django Applications
  3. Django REST Redux
  4. Test Driving a RESTful Django Contribution
  5. Evolving a RESTful Django Contribution

41 Comments

Comment by huangyi
2007-04-13 07:54:14

After you add registration to INSTALL_APPS list , app_directories template loader will automaticly look directory registration/templates for template file.

Comment by admin
2007-04-13 08:07:14

Doh! Thanks for catching that…

 
 
2007-04-25 10:13:58

[...] stone mind » Django Registration for Newbies — A nice tutorial for implementing user-driven account registration to Django. Django has a lot of great facilities to make this happen, but you just need to tie them all together for your specific needs. [...]

 
Comment by Kyle Fuller
2007-07-02 14:10:53

I am trying to install django-registration I have checked it out into /project/registration/ but when I add it to /project/settings.py. I get a few errors:

File “manage.py”, line 11, in ?
execute_manager(settings)
File “/home/fksource/django/django_src/django/core/management.py”, line 1736, in execute_manager
execute_from_command_line(action_mapping, argv)
File “/home/fksource/django/django_src/django/core/management.py”, line 1626, in execute_from_command_line
translation.activate(‘en-us’)
File “/home/fksource/django/django_src/django/utils/translation/__init__.py”, line 66, in activate
return real_activate(language)
File “/home/fksource/django/django_src/django/utils/translation/__init__.py”, line 41, in delayed_loader
return g[caller](*args, **kwargs)
File “/home/fksource/django/django_src/django/utils/translation/__init__.py”, line 66, in activate
return real_activate(language)
File “/home/fksource/django/django_src/django/utils/translation/trans_real.py”, line 194, in activate
_active[currentThread()] = translation(language)
File “/home/fksource/django/django_src/django/utils/translation/trans_real.py”, line 183, in translation
default_translation = _fetch(settings.LANGUAGE_CODE)
File “/home/fksource/django/django_src/django/utils/translation/trans_real.py”, line 168, in _fetch
app = __import__(appname, {}, {}, [])
ImportError: No module named registration

Am I doing something wrong?

Comment by Chris Hoeppner
2007-07-26 10:58:28

You’ve put registration into ‘project.registration’, rather than ‘registration’ as-is. Put it like that into installed apps.

 
 
Comment by admin
2007-07-02 14:31:43

Nothing jumps out at me…can you show me what you put in settings.py?

 
Comment by Collin
2007-07-02 15:16:53

Your directions are slightly incorrect.

You are not supposed to place the registration app inside your project, it is supposed to be on PYTHONPATH.

As the project dir is normally NOT on PYTHONPATH, your directions will lead to non-functional projects, as they try to load a module that does not exist :)

Comment by admin
2007-07-02 15:25:47

Thanks for stepping in with the solution. I must have made a misstep when I set up my Django environment initially.

 
 
Comment by baoilleach
2007-09-03 00:28:07

From a complete Django newbie, thanks for the tips – I’ll certainly be using this. For the record, the B-list describes a new version of the registration code (0.2) at http://www.b-list.org/weblog/2007/05/29/django-registration-update

Comment by admin
2007-09-03 04:24:57

Thanks, that’s good to know.

 
 
Comment by Joe
2007-10-01 02:52:54

Thanks for the tutorial, how about part two where you tie this together with an extended user profile module?

Comment by admin
2007-10-01 04:46:37

Good idea for a post. Lately, I’ve been doing more with Ruby on Rails than Django, but I’ll keep it in mind.

 
 
Comment by john
2007-10-29 20:35:45

I am trying to install django-registration but when I add it to settings.py. I get the following error:

Error: Couldn’t install apps, because there were errors in one or more models:
registration: cannot import name ugettext_lazy

can someone help me pinpoint where i’m going wrong?

Comment by admin
2007-10-30 04:01:04

John,

I hate to ask this, but is your Django installation up to date? I think the function being referred to is relatively new.

Comment by baoilleach
2007-11-05 13:44:43

I got caught by this too. As a newbie user of Django, the most annoying thing is the way that third-party extensions track the development version, rather than the release. Don’t get me wrong – django-registration works like a dream for me, except for this. Apparently, django-0.96.1 was released a week or two ago (not that you would know from the django home page) and I think this may fix the problem…although I’ve yet to confirm.

 
 
 
Comment by Sascha
2007-11-07 07:21:57

django-0.96.1 and problem: -> registration: cannot import name ugettext_lazy

;-(

 
Comment by baoilleach
2007-11-07 14:33:10

I got it to work for me by reinstalling django-registration 0.2 (django-0.96.1). (The strange thing is, I thought that I had already been using dj-reg 0.2…hmmm)

Comment by admin
2007-11-07 16:18:07

That’s great, thanks for letting us know!

 
 
Comment by Richard
2008-02-05 16:07:14

thanks! Great guide – more prescriptive than the txt files in the svn.

One question – the distribution does not contain any default templates. I’m a near noob o Python and a total noob to Django. Do you know where I can get some working template files to get me started?

thanks!!!!!!!!!!

Comment by admin
2008-02-05 18:32:10

Richard,

I’m glad you found this useful, although I should warn you that it was written for an older version of django-registration, so beware. It looks like in the more recent versions of the plugin, the author removed the example templates, so, if the start I gave above isn’t enough, you may want to look back at older versions of the plugin that still have the example templates. (According to the changelog, the templates were removed in the 0.3p4, 4 October 2007 version.)

 
 
Comment by Richard
2008-02-05 19:37:21

Hi, and thanks for getting back.

I digged a little deeper and found some django registration templates that work, here’s the link if anyone else is looking: http://code.djangoproject.com/browser/djangoproject.com/django_website/templates/registration

They are also ~5 months old, so am not sure if I may need to modify them. However am pleased to say I now have registration and auth working end to end (needs a little polish, bit it works).

Thanks once again for the guide!

- rich

Comment by admin
2008-02-06 03:28:16

Great! Thanks for following up with the link. From what I have seen the newest version of django-registration is largely backward compatible with any incompatible changes well documented in the changelog, so hopefully you won’t run into very many issues.

 
 
2008-02-28 16:32:08

[...] stone mind » Django Registration for Newbies (tags: development django framework login programming python registration authentication user) [...]

 
Comment by Thanos Panousis
2008-06-23 00:17:49

Great tutorial, thanks.

I ‘m using registration in my pet project, but I have one problem. One of the points of this project, beyond registering a user, is extending the django user model with a profile.

While you get access to a userProfile model when using django-registration, it is a bit unclear how to extend the RegistrationForm to include things from the UserProfile.

If I want to save for example, addresses for my users, I would like that to be a field in their registration form.

A follow-up clarifying this would be amazing!

 
Comment by Joey Doll
2008-08-19 21:27:45

Hi -
I just grabbed your plugin using subversion (svn checkout http://django-registration.googlecode.com/svn/trunk/registration/ registration), but the templates are nowhere to be found. Am I missing something?

Thanks,
Joey

Comment by Joey Doll
2008-08-19 21:45:35

Nevermind, I read through the docs. Your blog post made it sound like the templates were included. Thanks for the great work.

Comment by admin
2008-08-20 03:17:25

Sorry for the confusion. Also, I didn’t write the Django registration plugin, I’m just a grateful user.

 
 
 
Comment by Scot Hacker
2008-08-27 16:57:30

Thanks for the prefab templates linked above. I notice that set is missing a basic profile.html – does anyone have a copy to add? Thanks.

 
Comment by Scot Hacker
2008-08-27 17:01:31

Oops – password_reset.html is also missing from the set. Gracie.

 
2008-11-18 03:48:59

[...] Django Registration for Newbies [...]

 
Comment by Matt Youell
2008-12-05 19:03:02

This was totally helpful. Thanks a bunch!!

(Btw, a script on your page is driving FF on my Mac nuts. Could just be me though, I dunno.)

 
2009-02-16 12:29:26

[...] I took to get it up and running for a freshly created Django project. Other tutorials are available here, here and here, as well as in the official [...]

 
Comment by Vlad
2009-12-27 21:12:14

Interesting article, but unfortunately already new version Django and there is some changes

 
2010-03-09 16:56:55

[...] LinkedIn [...]

 
Comment by prakash
2010-09-29 23:54:59

Hello Sir,

i am not able to find user name,email id and password information into database.
where it’s located? how i can find it?

thanks
Prakash

 
Comment by Cássio Nandi
2011-03-16 17:07:28

Hello.

I can send emails using the example here http://docs.djangoproject.com/en/dev/topics/email/

But the django-registration is not sending emails.
How can I dig into the problem? The logs dont show any error…

I imagine that is this url that send the email.

url(r’^cadastro/usuario/$’, #register
register,
{ ‘backend’: ‘registration.backends.default.DefaultBackend’ },
name=’registration_register’),

 
Comment by Hank
2011-05-25 11:51:41

Any chance you’ll update this tutorial to the newest 0.8 alpha source?

 
Comment by Hank
2011-05-25 11:52:29

Any chance you’ll soon update this tutorial to the newest 0.8 alpha source?

Comment by admin
2011-05-25 11:59:30

Sorry, I don’t think I will be. I haven’t used Django for a while now, and this blog hasn’t gotten much attention in a long time either.

 
 
Comment by sanket
2011-08-28 16:46:46

Thank you so much for posting this article. I am new to django and as the django-registration comes without the templates it was kind of difficult for me to get it working. but because of this article. I got the whole registration component working in few hours.

Thanks a lot and Keep the good work up
sanket

 
2013-01-28 18:17:09

I feel this is one of the most vital info for me. And i
am glad reading your article. However wanna statement on few basic issues, The site style is ideal, the articles
is really great : D. Good activity, cheers

 

Sorry, the comment form is closed at this time.