Для того, чтобы сделать оформление страницы авторизации в едином стиле с оформлением всего сайта, можно подготовить шаблон оформления и подменить шаблон url, чтобы отдавать требуемое нам представление страницы с требуемым шаблоном. Также это может быть полезно для внедрения функционала блокировок от подбора пароля и более интеллектуального перенаправления пользователя на страницы сайта после авторизации в зависимости от того, имеет ли пользователь статус персонала или нет.
Для работы с авторизацией пользователей предлагаю использовать отдельное приложение/модуль, который будет называться accounts.
Форму авторизации писать не требуется, поскольку можно воспользоваться стандартной формой AuthenticationForm , которую необходимо будет использовать в шаблоне страницы авторизации.
Структура модуля accounts
accounts/ templates/ accounts/ login.html login_widget.html __init__.py admin.py apps.py models.py special_func.py urls.py views.py
В данном модуле используется два шаблона:
- login.html - это шаблон для страницы авторизации
- login_widget.html - это шаблон для виджета авторизации, который может быть помещён на любой странице сайта, чтобы пользователь мог авторизоваться не только со страницы авторизации, но и с любой страницы со статьёй, например.
Файл special_func.py содержит некоторые полезные функции, как например, получение предыдущего Url из запроса , чтобы перенаправить пользователя обратно на страницу, где пользователь авторизовался.
login_widget.html
Напоминаю, что я использую django_bootstrap3 на сайте, поэтому и шаблон будет с его использованием.
<form id="contact_form" action="{% url 'accounts:login' %}" method="post"> {% load bootstrap3 %} {% csrf_token %} {% bootstrap_form login_form %} {% buttons %} <div class="form-group"> <button type="submit" class="btn btn-primary">Войти</button> </div> {% endbuttons %} </form>
login.html
В шаблоне авторизации добавляется данный виджет. По тому же самому принципу можно добавлять виджет авторизации на любой странице в любом месте сайта.
{% extends 'home/base.html' %} {% block content %} <div class="col-md-offset-3 col-md-6 voffset-60"> <h1>Войти на сайт</h1> {% include 'accounts/login_widget.html' %} </div> {% endblock %}
urls.py файлы
Для того, чтобы подменить страницу авторизации, да и в целом использовать виджет авторизации, необходимо в файле urls.py вашего проекта добавить следующие шаблоны url.
from django.conf.urls import url, include from django.contrib import admin from accounts.views import ELoginView # Представление для авторизации из модуля accounts # Чтобы перехватить страницу авторизации, необходимо # прописать путь к этой странице перед url админ-панели # и указать представление, которое будет теперь обрабатывать авторизацию urlpatterns = [ url(r'^admin/login/', ELoginView.as_view()), url(r'^admin/', admin.site.urls), url(r'^accounts/', include('accounts.urls')), # также добавим url модуля авторизаций ]
urls.py файл модуля accounts будет выглядеть следующим образом:
# -*- coding: utf-8 -*- from django.conf.urls import url from . import views app_name = 'accounts' urlpatterns = [ url(r'^login/$', views.ELoginView.as_view(), name='login'), ]
settings.py и apps.py
Не забудьте зарегистрировать модуль авторизаций в настройках сайта.
apps.py
from django.apps import AppConfig class AccountsConfig(AppConfig): name = 'accounts'
settings.py
INSTALLED_APPS = [ 'accounts.apps.AccountsConfig', ]
views.py
А теперь перейдём к представлению, которое будет обрабатывать авторизацию, как со страницы авторизации, так и с люой другой страницы.
# -*- coding: utf-8 -*- from urllib.parse import urlparse from django.shortcuts import redirect, render_to_response from django.contrib import auth from django.template.context_processors import csrf from django.views import View from django.contrib.auth.forms import AuthenticationForm from .special_func import get_next_url class ELoginView(View): def get(self, request): # если пользователь авторизован, то делаем редирект на главную страницу if auth.get_user(request).is_authenticated: return redirect('/') else: # Иначе формируем контекст с формой авторизации и отдаём страницу # с этим контекстом. # работает, как для url - /admin/login/ так и для /accounts/login/ context = create_context_username_csrf(request) return render_to_response('accounts/login.html', context=context) def post(self, request): # получив запрос на авторизацию form = AuthenticationForm(request, data=request.POST) # проверяем правильность формы, что есть такой пользователь # и он ввёл правильный пароль if form.is_valid(): # в случае успеха авторизуем пользователя auth.login(request, form.get_user()) # получаем предыдущий url next = urlparse(get_next_url(request)).path # и если пользователь из числа персонала и заходил через url /admin/login/ # то перенаправляем пользователя в админ панель if next == '/admin/login/' and request.user.is_staff: return redirect('/admin/') # иначе делаем редирект на предыдущую страницу, # в случае с /accounts/login/ произойдёт ещё один редирект на главную страницу # в случае любого другого url, пользователь вернётся на данный url return redirect(next) # если данные не верны, то пользователь окажется на странице авторизации # и увидит сообщение об ошибке context = create_context_username_csrf(request) context['login_form'] = form return render_to_response('accounts/login.html', context=context) # вспомогательный метод для формирования контекста с csrf_token # и добавлением формы авторизации в этом контексте def create_context_username_csrf(request): context = {} context.update(csrf(request)) context['login_form'] = AuthenticationForm return context
Для Django рекомендую VDS-сервера хостера Timeweb .
Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильный редирект. При переходе по ссылке /test/, меня редиректит на страницу авторизации(как и должно происходить в моем случае), после авторизации меня втупую перебрасывает на главную а не на предидущую страницу.