Реклама

Django - Урок 017. Кастомизированная страница авторизации на Django

РуководствоDjangoDjango, login, авторизация2369

Для того, чтобы сделать оформление страницы авторизации в едином стиле с оформлением всего сайта, можно подготовить шаблон оформления и подменить шаблон 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

Реклама

Комментарии

Комментарии

Только авторизованные пользователи могут оставлять комментарии.
Пожалуйста, Авторизуйтесь или Зарегистрируйтесь
Последние комментарии
  • EVILEG
  • 13 июля 2017 г. 2:12

Qt/C++ - Урок 023. Перетаскивание QGraphicsItem на QGraphicsScene мышью

Ну например так можете сделать.void MoveItem::mousePressEvent(QGraphicsSceneMouseEvent *event){ if (QApplication::mouseButtons() == Qt::RightButton) { this->deleteLa...

  • Mark
  • 13 июля 2017 г. 1:26

Qt/C++ - Урок 023. Перетаскивание QGraphicsItem на QGraphicsScene мышью

Подскажите пожалуйста как в данном проекте по перетаскиванию организовать удаление объекта со scene методом delete item, допустим при щелчке ПКМ по объекту QGraphicsScene. Мои попытки оказалис...

  • EVILEG
  • 10 июля 2017 г. 21:34

Qt/C++ - Урок 048. QThread - работа с потоками с помощью moveToThread

А что делали? Повторяете урок или как? Пытались просто скачать проект в конце статьи и запустить?

Qt/C++ - Урок 048. QThread - работа с потоками с помощью moveToThread

У меня происходит переполнение счетчика count, появляется ошибка malloc(): memory corruption (fast). Не подскажите, как с этим бороться?

  • EVILEG
  • 9 июля 2017 г. 2:07

GameDev на Qt - Урок 3. Уничтожение противников

Поэтому в пятом уроке есть исходники всего проекта )))). Вообще, все эти материалы были не предыдущей версии сайта, которая на WordPress. Во время переноса мог что-то потерять.

Сейчас обсуждают на форуме

Как реализовать отправку e-mail

Возможно что уже и нет необходимости в почтовом клиенте, но в своё время так же столкнулся с данной проблемой в QT. Нашел один интересный проект под названием libqxt, там реализовано дов...

  • BlinCT
  • 18 июля 2017 г. 0:00

тестирование классов в QT

Это был вопрос или утверждение? Не понятно что вы хотели этим сказать. Интересное у вас обращение.

  • Asteri
  • 14 июля 2017 г. 12:23

css

Делюсь, может, пригодится когда-нибудь) QTableView QHeaderView { background-color: #ffffff; } Вот так эта проблема лечится, градиент задать не получается, но хоть...

  • EVILEG
  • 12 июля 2017 г. 19:52

QSqlQuery выполнение sql запросов из файла

Мне думается, что это уже будет дело вкуса и вашего взгляда на проект. Если Вы действительно собираетесь просто скармливать своему софту SQL скрипты, которые должны будут выполняться для...

QML Canvas + Line. Bug?

Вот оно что, значит не баг) Спасибо