This is the first post in the Django series published on solutoire.com. In the series I’ll discuss and solve some of the problems I ran across while struggling with Python and Django in particular. The subjects are handled in a fast pace and the posts in this series will get you up and running quickly. The posts will mainly consist of code examples and a few explanations. Most of the time I’ll refer to other websites for thorough explanations.

In this post I’ll explain how to create a custom log in page. We’ll write our own view function and form that handles the authentication. In the next post I’ll explain how to create a custom authentication backend, that lets you log in users by their email addresses instead of their username.

Setting Up The Project

I assume you’ve already installed Django and that you have a database. First step is to create a new project (in my case called ’solutoire’). Then, create an app in the project called ‘auth’. Of course you can name both whatever you like. Fire the following commands on your command line:

// Create a new project:
# django-admin.py startproject solutoire
// Create the authentication app:
# manage.py startapp auth

Now set up your project as described in the Django Tutorial. Make sure you’ve added the database settings in settings.py.

Next thing you need to do is to sync the database. Make sure you create a superuser and write down the credentials (especially the email address and the password). Run the following commands:

// Sync the database, create a superuser
# manage.py syncdb
// Start the development server at http://127.0.0.1:8080
# manage.py runserver 8080

Creating A Log in Page

Django already has built in User authentication. To start using it, make sure django.contrib.auth is in the INSTALLED_APPS tuple. If you don’t have it yet, add it, and run the manage.py syncdb again, this creates the tables in the database that you’ll need for authentication. Django also comes with several authentication views, but for now, we’ll write our own.

To facilitate a log in page, create a new directory ‘templates’ in project folder and create a file called auth.html inside it. In settings.py, add the absolute path to template directory to the TEMPLATE_DIRS setting. In my case, it looked like:

TEMPLATE_DIRS = (
    'E:/Django/Projects/solutoire/templates'
)

We also need a view function and a template. Open up auth/views.py and paste the

// auth/views.py
from django.shortcuts import render_to_response
from django.contrib.auth import authenticate, login

def login_user(request):
    state = "Please log in below..."
    username = password = ''
    if request.POST:
        username = request.POST.get('username')
        password = request.POST.get('password')

        user = authenticate(username=username, password=password)
        if user is not None:
            if user.is_active:
                login(request, user)
                state = "You're successfully logged in!"
            else:
                state = "Your account is not active, please contact the site admin."
        else:
            state = "Your username and/or password were incorrect."

    return render_to_response('auth.html',{'state':state, 'username': username})

Now, copy & paste the following HTML to the auth.html file. This is the template for the log in view. To read more about Django templates, go read Django Template Language and Built-in template tags and filters.

// templates/auth.html
<!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>
<title>Log in</title>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<style>
body{
	font-family:Arial,Helvetica,sans-serif;
	font-size: 12px;
}
</style>
</head>
<body>
	{{ state }}
	<form action="/login/" method="post">
		{% if next %}
		<input type="hidden" name="next" value="{{ next }}" />
		{% endif %}
		username: 
		<input type="text" name="username" value="{{ username}}" /><br />
		password:
		<input type="password" name="password" value="" /><br />

		<input type="submit" value="Log In" />
	</form>
</body>
</html>

In order to see the form with your browser, the urlpatterns variable in urls.py in the project root should have an entry that points to the login_user function defined in auth/views.py:

from django.conf.urls.defaults import *

# Uncomment the next two lines to enable the admin:
# from django.contrib import admin
# admin.autodiscover()

urlpatterns = patterns('',
    (r'^login/$', 'auth.views.login_user'),
)

The form looks like this when you’re not logged in:

login_form1
The log in form.

As you can see, the render_to_response function passes two variables to the auth.html template we’ve just created. Now we have everything in place for logging in users. Try it yourself, use the credentials you just wrote down when you ran the manage.py syncdb command (to log in, point your browser to http://127.0.0.1:8080/login). This code is everything you need with Django to have your own log in page. However, Django also comes with some predefined log in views. You can read more about those default templates at the Django Documentation

What’s next

In the next post in the Django series we’ll will write our own authentication backend. The custom backend enables us to let users log in by their email address, instead of their username. Of course you can change the backend to your likings, for example, let users log in by their first name, email address and their password.

Download

You can download all the code above in a zip file. When you use this code, make sure you change paths and credentials.