Categories

  • jekyll
  • development

So you have started up a shiny new Django project and probably gone through the getting started tutorial. Somewhere along that line you are shown how to get the “free” functionality of the Django admin pages, along with authentication into the admin section. The next logical step is to say “wow, that’s great I should add some authentication to the views I have created”. A quick Google search will inform you, good. fucking. luck.

So after a couple days of messing around with this I have finally cobbled together a solution. Sharing is caring and such:

First things first, lets edit your sites urls.py file to add in our login and logout pages by adding the following:

urlpatterns += patterns('django.contrib.auth.views',
  (r'^/accounts/login/$', 'login', {'template_name': 'accounts/login.html'}),
  (r'^/accounts/logout$', 'logout',{'template_name': 'accounts/logout.html'}),
)

No by default these two urls will use django.contrib.autu.views for it’s login and logout functionality and as such it will attempt to load the following templates.

  1. /path/to/your/django_templates/registration/login.html
  2. /path/to/your/django_templates/registration/logout.html

But since you have used the parameter:

{'template_name': 'accounts/login.html'}

You have now specified your own location and filename for the template. First off head over to your django_templates folder and create the accounts folder. Within it lets create the following files:

base.html

<html>
  <head></head>
  <body>
    {% block content %}
    {% endblock %}
  </body>
</html>

login.html

{% extends "accounts/base.html" %}
{% block title %}Log in{% endblock %}
{% block head %}Log in{% endblock %}
{% block content %}
    {% if form.has_errors %}
    <p> Username or password didn't work. Please enter them again </p>
    {% endif %}

    <form method="post" action=".">
        {% csrf_token %}
        <p><label for="id_username">Username:
            </label>{{ form.username }}</p>
        <p><label for="id_password">Password:
            </label>{{ form.password }}</p>
        <input type="hidden" name="next"
            value="{{ next  }}" />
        <input type="submit" value="Log in" />
    </form>

{% endblock %}

logout.html

{% extends "accounts/base.html" %}

{% block content %}

<p>You have been logged out.</p>
<a href="{% url django.contrib.auth.views.login %}">Login again</a>

{% endblock %}

Ok we’re almost free, now we just need to specify what pages require user authentication. Thankfully this is a mercifully painless step. All that is required is to add the @login_required annotation to any view that you wish to secure, like so:

Edit the views.py file for the application in question.

from django.contrib.auth.decorators import login_required

@login_required()
def index(request):
  ... all the display business...

Now when you head to the index location of your application you should be redirected to the login page, where you can use a username password that you have generated in the /admin/ section, or the initial Django administrator account. WOOO!