Commit be57a7fd authored by Adrian Holovaty's avatar Adrian Holovaty
Browse files

Fixed #849 -- Improved login_required view decorator to save query-string...

Fixed #849 -- Improved login_required view decorator to save query-string parameters. Also added documentation on the django.contrib.auth.views.login view to docs/authentication.txt

git-svn-id: http://code.djangoproject.com/svn/django/trunk@2954 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent 75df1327
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
from django.contrib.auth import LOGIN_URL, REDIRECT_FIELD_NAME
from django.http import HttpResponseRedirect
from urllib import quote

def user_passes_test(test_func, login_url=LOGIN_URL):
    """
@@ -11,7 +12,7 @@ def user_passes_test(test_func, login_url=LOGIN_URL):
        def _checklogin(request, *args, **kwargs):
            if test_func(request.user):
                return view_func(request, *args, **kwargs)
            return HttpResponseRedirect('%s?%s=%s' % (login_url, REDIRECT_FIELD_NAME, request.path))
            return HttpResponseRedirect('%s?%s=%s' % (login_url, REDIRECT_FIELD_NAME, quote(request.get_full_path())))

        return _checklogin
    return _dec
+53 −0
Original line number Diff line number Diff line
@@ -330,6 +330,59 @@ introduced in Python 2.4::
    * If the user is logged in, execute the view normally. The view code is
      free to assume the user is logged in.

Note that you'll need to map the appropriate Django view to ``/accounts/login/``.
To do this, add the following line to your URLconf::

    (r'^accounts/login/$', 'django.contrib.auth.views.login'),

Here's what ``django.contrib.auth.views.login`` does::

    * If called via ``GET``, it displays a login form that POSTs to the same
      URL. More on this in a bit.

    * If called via ``POST``, it tries to log the user in. If login is
      successful, the view redirects to the URL specified in ``next``. If
      ``next`` isn't provided, it redirects to ``/accounts/profile/`` (which is
      currently hard-coded). If login isn't successful, it redisplays the login
      form.

It's your responsibility to provide the login form in a template called
``registration/login.html``. This template gets passed three template context
variables:

    * ``form``: A ``FormWrapper`` object representing the login form. See the
      `forms documentation`_ for more on ``FormWrapper`` objects.
    * ``next``: The URL to redirect to after successful login. This may contain
      a query string, too.
    * ``site_name``: The name of the current ``Site``, according to the
      ``SITE_ID`` setting.

Here's a sample ``registration/login.html`` template you can use as a starting
point. It assumes you have a ``base.html`` template that defines a ``content``
block::

    {% extends "base.html" %}

    {% block content %}

    {% if form.has_errors %}
    <p>Your username and password didn't match. Please try again.</p>
    {% endif %}

    <form method="post" action=".">
    <table>
    <tr><td><label for="id_username">Username:</label></td><td>{{ form.username }}</td></tr>
    <tr><td><label for="id_password">Password:</label></td><td>{{ form.password }}</td></tr>
    </table>

    <input type="submit" value="login" />
    <input type="hidden" name="next" value="{{ next }}" />
    </form>

    {% endblock %}

.. _forms documentation: http://www.djangoproject.com/documentation/forms/

Limiting access to logged-in users that pass a test
---------------------------------------------------