User authentication with django-registration

Please note that this guide is not updated with instructions for the latest version of django-registration. Some things in the steps below may no longer be valid. Comments have been disabled.

The built-in user authentication system in Django is great, but unfortunately it lacks support for sending activation emails to newly registered users. Enter the django-registration application, which adds registration and account activation on top of Django’s standard views for user authentication.

Although certainly not the first of its kind, this post will cover the steps 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 documentation.

Step 1 — install django-registration
Instructions on how to install django-registration are covered nicely by the official overview document. You can also simply copy the registration folder directly to your project folder, which enables you to modify the contents of the package specifically for your project, should you wish to do so.

Step 2 — update settings.py
Add the registration application to the INSTALLED_APPS tuple in settings.py. Also add django.contrib.admin if you want to make use of Django’s admin system to handle user accounts (of course you do!). It might look like this:

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

I also added the following settings:

ACCOUNT_ACTIVATION_DAYS = 2
EMAIL_HOST = 'localhost'
DEFAULT_FROM_EMAIL = 'webmaster@localhost'
LOGIN_REDIRECT_URL = '/'

Strictly speaking, only the first setting is required. It controls how many days emailed activation keys are valid.

EMAIL_HOST should be set to whatever host name your mail server is on. It defaults to ‘localhost’, but it’s explicitly set in the above example for clarity. You should also change the DEFAULT_FROM_EMAIL setting to show a proper sender email address for your activation emails.

Finally, LOGIN_REDIRECT_URL controls where a user is redirected after successful login by the contrib.auth.login view. The default value /accounts/profile/ is fine if you intend to map a view to that URL, but django-registration doesn’t do this for us so we’ll just use ‘/’ for now.

Step 3 — setup database
In addition to the standard Django user models, django-registration needs an additional model (RegistrationProfile) for storing activation keys that are sent out. Set this model up in the database by running:

python manage.py syncdb

Step 4 — update urls.py
The root urls.py needs to be updated with mappings for the registration application and admin. django-registration maintains its own mappings inside ./registration/urls.py, so we just delegate to that file:

from django.conf.urls.defaults import *
from django.views.generic.simple import direct_to_template
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    (r'^admin/(.*)', admin.site.root),
    (r'^accounts/', include('registration.urls')),
    (r'^$', direct_to_template, 
            { 'template': 'index.html' }, 'index'),
)

This example also adds a mapping for the ‘/’ URL we added a redirect to in step 2, which directly forwards to an index.html template.

Step 5 — create view templates
All that remains now is to create rendering templates for the registration views. They should go into a ‘registration’ folder under your template root (TEMPLATE_DIRS in settings.py).

django-registration maps URLs to the standard django.contrib.auth.views, so the following templates need to be created:

login.html — user login form
logout.html — shown after a user has logged out
password_change_form.html — password change form
password_change_done.html — shown after successful password change
password_reset_form.html — ask user for email to send password-reset mail to
password_reset_email.html — template for password-reset mail
password_reset_done.html — shown after password-reset email has been sent
password_reset_confirm.html — ask user for new password after reset
password_reset_complete.html — shown after successful password reset

Note that the password_reset_confirm and password_reset_complete views are missing from the official documentation, but it’s possible to see how they can be used in the Django source code here, here, and here.

Additionally, the following templates specific to django-registration need to be created:

registration_form.html — user registration form
registration_complete.html — shown after a user has registered
activation_email_subject.txt — subject of activation email
activation_email.txt — template for activation email
activate.html — shown after a user has activated his account

I’ve created very basic example implementations of these templates that you can check out here.

Step 6 — change site name and domain
The email templates will normally output both the domain name and display name for your web site. To change the default value of “example.com” to the name of your web site you need to log in to the admin system and go to the Sites section (/admin/sites/site/), where you can edit this.

Step 7 — done
That should be all, I hope. ;-)

About these ads

40 responses to “User authentication with django-registration

  1. Michael T.

    Thanks for a great tutorial!

  2. devdoodles

    Thanks, I’m glad you found it useful!

  3. If you know any place where I can find information about how to extend the functions you would brighten my day.

    I’m trying to have different classes of users: simple users can register themselves and automatically go in the simple group and on the other side special users need an admin approval and go to the special group.

    I’m swiming in the code and django doc right now but any light would be appreciated. Thanks for this article.

  4. devdoodles

    Although it’s not quite clear to me what you want to do, it sounds as if you might want to read up on user permissions and groups in the Django auth documentation. By checking which permissions a user have, or which groups he/she belongs to, you can adapt how the site works for your two user groups:

    http://docs.djangoproject.com/en/dev/topics/auth/

    As for the actual registration step, I’m not sure how you want to handle the “special” users or what criterion marks a user as special. If both groups are meant to be able to register on their own and by default go into the “simple” group, then I think you don’t need to change the django-registration code at all. The admin approval step could just be someone updating the permissions/groups for the user in the admin interface.

    However, if the special-group users should not become active at all before admin approval has been made, you would have to change the register() and activate() views (and dependent logic) in django-registration to accommodate this.

  5. aleksandar

    Link with templates is dead. Can you please reupload.

  6. devdoodles

    Sorry about that, my server got taken down as a result of the vaserv.com wipe this week. The link should be working again within an hour.

  7. Michael h, DK

    Hi and thanks for posting this fine article howto.

    I have a little problem though. Cant login. I keep getting thrown out. I get fine error msg’es when I use wrong username or passw. But when I use the correct username and passw, then I just get thrown back to the login.
    Any idea what I did wrong?
    Thanks again :o)

  8. Michael h, DK

    Hi again. It must be something mysterious, cause it seems to work in another browser. I played alot with the reset password stuff and that might have messed up something in session. I dont know… But I think its solved. Thanks anyway :o)

  9. Thanks for the example templates – very much appreciated.

  10. Thank you very much! Helped me a lot.
    I did the following to have the link sent through my gmail-account:
    EMAIL_USE_TLS = True
    EMAIL_HOST = ‘smtp.gmail.com’
    EMAIL_HOST_USER = ‘@gmail.com’
    EMAIL_HOST_PASSWORD = ”
    EMAIL_PORT = 587

  11. Thank you, this tutorial helped me a lot. Especially zipped templates file.

  12. Thanks guys, I appreciate the feedback!

  13. Hello, I am with some trouble… I will appreciate any help…
    I follow the tutorial and made double check but I still getting some problem.
    When I access “login” I get this error:
    DoesNotExist at /accounts/login/

    if I access /accounts/register/ the template will open without problem, but after submit another error happen…

    Could someone help me?

    You can see this errors accessing http://www.spire.com.br

    Thanks

  14. Well… The problemas was solved… I just droped all databases and re-create… But I have no idea why it works now…

  15. Good that you found a solution, even if it was no explanation. :-) Did you get any other message than DoesNotExist?

    The only suggestion I found from a quick search was that some people got this problem when django.contrib.sites wasn’t loaded or when there was no site model matching the site ID. If this was the problem in your case I don’t know…

  16. Yes devdodles, I think the problem is around there :-)
    I deleted the “example.com” and created one with my domain. Maybe there is the trouble, I should just rename and not delete/create. But I am not really sure if it was the problem.

    Thanks anyway! Everything is working now.

  17. Maybe a silly question. :-p

    After login I am loosing auth session for some pages. If I access “accounts/login/”,”accounts/logout/”,””accounts/register/” the session always will be there, but if I access different page I cant access the user variable.

    This is strange because I am using the same “base.html” for all pages and inside has the logic “if user.is_authenticated”, how I said this condition is true just when I access pages that have “accounts” in the URL.

    in the settings file I enabled theses three middleware:

    MIDDLEWARE_CLASSES = ( ‘django.middleware.common.CommonMiddleware’, ‘django.contrib.sessions.middleware.SessionMiddleware’, ‘django.contrib.auth.middleware.AuthenticationMiddleware’, )

    Thanks

  18. I’m guessing you’re not passing a RequestContext() to the templates that aren’t working. The user object is only available in RequestContexts, not the base Context that is passed by default. If you’re using render_to_response() you can pass a RequestContext by adding context_instance=RequestContext(request) as a parameter to the call.

  19. Yes, you are right.

    I just needed import “from django.template import RequestContext”
    and add this parameter.

    Thanks a lot.

  20. Pingback: Django IA: Registration-Activation « streamhacker.com

  21. Hi! Nice explanation.
    Just one question: how do you setup a link in order to activate users?

    Something like
    accounts/activation/?key=oijr32orj23rj32orj34o

    And then call the activate_user(key) in a view?

  22. Christoffer Torris Olsen

    Thanks a bunch for the very useful template boilerplate. Saved me some time there :)

  23. Greate article, very useful !!
    Thnaks your share.

  24. thank you for good instruction!

  25. Thanks, I appreciate your comments.

  26. Thanks for the nice tutorial. I wonder if you can help me though… I’m wanting to set a special permission group for the user automatically who signs up using django-registration. Is there anyway of doing this without messing with the app itself?

  27. Thanks for this tutorial.
    How can I use both RegistrationFormUniqueEmail and RegistrationFormTermsOfService in my registration form?

  28. Thanks guys. It’s been a while since I worked with this, so I’m afraid I can’t help you with any details.

    @littlejim84 — the only thing that comes to mind is to listen in on created or activated users through the signal framework. The latest version of django-registration seems to send custom signals for user registration and activation, but in previous versions you might have to listen on the User model directly instead.

    @Ste — I’ve never done this, but my guess is you’d have to create a form class of your own that inherits from whichever of the other forms is easiest, and then adds the functionality that you miss from the other. In the URL configuration you should then be able to pass an instance of your form to the register view.

  29. This is a great post. It helped me understand the workings of django-registration. I’ve got one remaining questions. First, regarding activate.html, the blog says this is shown after a user has activated his account. This must be referring to the upper half of activate.html, which is dependent on the existence of “account”. On the contrary, I find this is normally the role of activation_complete.html (URL: accounts/activate/complete/). I find that account.html (bottom half, when account does not exist) comes in on a URL of /accounts/activate/ followed by a (test) corrupt hash. So what condition activates the upper half of activate.html?

  30. Tom, thanks for the feedback. The latest version of django-registration, which I believe you are using, brings some changes to the views being used (among other things) , and this guide is unfortunately not up to date in that regard.

    You can find more info here about the new version:

    http://docs.b-list.org/django-registration/0.8/

  31. Thanks a lot for this article and the example templates. :) That’s a big time-saver

  32. Thankyou very much for this nice article and sample templates.

  33. devdoodles

    Thanks, you’re welcome!

  34. Hi,
    Thanks for this tutorial and post I was looking for the same script.
    But I think you are gonna hate me for this. As Im a newbie to django I dont knowmy way around much but got it up and runnign with a few problems Im facing and will appreciate if you can help me with this.
    I have used my gmail account to send email. Now the problem is the link that i get in d mail is like:
    Activate account at example.com:

    http://example.com/accounts/activate/68592315e0f589a0cee9557d4f9913a7e6166dbd/

    Link is valid for 7 days.

    I am not sure if this is a silly question but i havnt got a running website so I have changed the template for activation_account_text file and changed it to my localhost. now when i’m trying to click that link it opens a page saying
    “Account Activation Failed”
    What am I doing wrong..
    I hope the info here is sufficient if not please feel free to ask.

  35. devdoodles

    Sorry, I can’t say for sure, as that’s a generic error message shown when something goes wrong, but it does not say what. Also, this guide is not updated with instructions for the latest version of django-registration, so it’s possible something is broken because of that. That said, it could be that your key is not valid for some reason, that it has expired, or that your user account is already activated. Good luck.

  36. Pingback: Starting From Scratch « Becoming a Builder.

  37. Pingback: User authentication with django-registration « Becoming a Builder.

  38. Pingback: django registration on django non rel « JoinWithJack

  39. Pingback: Django Python Ubuntu 10.04 « Collective Goods

  40. Pingback: Django-registration add form | Technical support, Computer, programming issue, issue tracking, quality assurance