2016-08-04

setting up basic Django authentication

So one of the things that Django does not currently do (as of 1.10) is provide a built-in login screen template for your app (like web2py does), even though it provides the views and forms as part of django.contrib.auth, but that's most probably because of its use in the admin app. So here's how you'd setup a basic one, using the built-in views:

First, the default LOGIN_URL is the urlpath /accounts/login, which you can see in your Django's django/conf/global_settings.py. You can switch your project to use a different one. In django/contrib/auth/views.py, we notice that the login() defaults its template_name to 'registration/login.html'. You can switch this in your project's URL conf. In any case, if we stick to the defaults we need to add the following to our project's URL conf in myproject/urls.py:

from django.contrib.auth.views import login, logout

urlpatterns = [
    # the other urlpatterns for your project
    url(r'^accounts/login/$', login),
    url(r'^accounts/logout/$', logout),
]

Next, assuming that in myproject/settings.py, APP_DIRS is True, then we need to build in the page template for the form at myproject/myapp/templates/registration/login.html:

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

{% block content %}

  <div class="container">

    {% if form.errors and not form.non_field_errors %}
      <p class="errornote">
      {% if form.errors.items|length == 1 %}
        "Please correct the error below."
      {% else %}
        "Please correct the errors below."
      {% endif %}
      </p>
    {% endif %}

    {% if form.non_field_errors %}
      {% for error in form.non_field_errors %}
        <p class="errornote">
        {{ error }}
        </p>
      {% endfor %}
    {% endif %}

    <form class="form-signin" method="POST">
      {% csrf_token %}
      <h2 class="form-signin-heading">Please sign in</h2>
      <label for="inputUser" class="sr-only">User Name</label>
      <input type="text" name="username" id="inputUser" class="form-control" placeholder="User Name" maxlength="151" required autofocus>
      <label for="inputPassword" class="sr-only">Password</label>
      <input type="password" name="password" id="inputPassword" class="form-control" placeholder="Password" required>
      <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
    </form>
  
  </div>

{% endblock %}

NOTE: Because the builtin-view login is called, which renders the builtin AuthenticationForm, you don't specify a form action in your login form template. Doing so will result in a Error NoReverseMatch on Reverse Django URL!

Then in the view that you want to protect:

from django.http import HttpResponse
from django.contrib.auth.decorators import login_required

@login_required
def index(request):
    # yadda
    return HttpResponse(yourviewtemplate.render(Context()))

Then when you go to the index view, you get a screen that looks like:

Note that the base.html references bootstrap.css and friends

No comments:

Post a Comment