Часто возникает необходимость создать на сайте панель, через которую можно будет авторизовать пользователя на любой странице.
Делается это достаточно просто.
Сначала создадим шаблон этой панели:
{% load i18n %}
<div>
{% if user.is_authenticated %}
<form method="post" action="{% url auth:logout %}?next={{ request.path|urlencode }}">
{% csrf_token %}
<input type="submit" name="logout" value="{% trans "Logout" %}"/>
<input type="submit" name="admin" value="{% trans "Site Setup" %}"
onclick="document.location='{% url admin:index %}'; return false;"/>
</form>
{% else %}
<form method="post" action="{% url auth:login %}?next={{ request.path|urlencode }}">
{% csrf_token %}
<input type="text" name="username" maxlength="30" id="id_username"/>
<input type="password" name="password" id="id_password"/>
<input type="submit" name="login" value="{% trans "Login" %}"/>
</form>
{% endif %}
</div>
Этот шаблон можно подключать в header
сайта с помощью тега {% include %}
для отображения панели на каждой странице сайта.
Если пользователь не авторизован, то показываем ему поля для ввода логина и пароля, в противном случае показываем ему кнопки выхода и перехода к админке.
Обратите внимание, что в шаблоне две формы, как раз для этих двух случаев. Из-за простоты форм я их задаю прямо в шаблоне, это позволяет не писать лишний код во вьюхах сайта.
С помощью request.path|urlencode
я обеспечиваю передачу информации о текущей странице, чтобы иметь возможность вернуться на неё после выполнения авторизационных действий.
Теперь разберёмся с подключением кода.
url(r'^admin/', include(admin.site.urls)),
url(r'^auth/login/$', 'src.users.views.login'),
url(r'^auth/', include('django.contrib.auth.urls', namespace='auth')),
Для работы сайта всегда требуется админка, да и я предоставляю кнопку для перехода на неё. Соответственно, сначала подключаем админку.
Затем я подключаю в именованное пространство auth
функционал стандартного модуля авторизации Django. Но поведение его вьюхи login
меня немного не устраивает, поэтому именно её я переопределяю. Если вы помните, то порядок определения URLs имеет значение, поэтому я свою вьюху прописываю чуть раньше.
Теперь рассмотрим саму вьюху:
def login(request):
u"""
Вызывает соответствующее представление Django, анализирует результат.
В случае ошибки генерирует сообщение и возвращает пользователя на прежнюю страницу.
"""
response = original_login(request)
if isinstance(response, HttpResponseRedirect):
return response
else:
messages.error(request, _(u'Your credentials are wrong. Sorry.'))
return_to = request.REQUEST.get(REDIRECT_FIELD_NAME, reverse('frontend:index'))
return HttpResponseRedirect(return_to)
Свою вьюху я сделал лишь для того, чтобы выдавать сообщение об ошибке при авторизации через стандартную систему сообщений Django. Если вы верите, что пользователь никогда не допустит ошибок или вас это просто не волнует, то можно всё сделать ещё проще :)
Ну а само сообщение об ошибке я вывожу через jGrowl (такая jquery библиотека). Эту часть я оставлю в качестве домашнего задания.
P.S. Всё проверено на Django 1.4. Есть мнение, что и на более старых версиях этот рецепт будет работать.