Django 31. Форма авторизации и кнопка выхода
В этом посте, мы добавим возможность входа и выхода с сайта.
Дополнительные материалы
Для скачивания материалов необходимо войти или зарегистрироваться
Файлы также можно получить в Telegram-боте по коду: 896551
Реклама
Продолжаем развивать проект.
В этом и нескольких следующих постах, мы добавим возможность пользователям регистрироваться, авторизовываться на сайте и выходить с него, сбрасывать свой пароль, а также реализуем страницу с профилем пользователя.
И начнём мы с создания нового приложения.
Приложение user_app.
В прошлом посте я упоминал о важности разделения разных логических блоков на Django-приложения. Поэтому для пользователей сделаем отдельное приложение user_app
.
Для создания нового приложения выполните в терминале следующую команду:
python manage.py startapp user_app
Создастся новая директория с основными файлами.
Сразу откроем файл settings.py
и добавим новое приложение в список INSTALLED_APPS
- 'user_app.apps.UserAppConfig',
Авторизация.
Форма авторизации.
Создадим форму авторизации.
На самом деле, делать этого не обязательно.
Можно воспользоваться встроенной формой, собственно от которой будем наследоваться, однако тут встаёт вопрос с её отображением. У стандартной формы отсутствуют стили.
Можно конечно их прописать с помощью CSS-селекторов, но у меня в данный момент используется Bootstrap5.
Для того чтобы воспользоваться его возможностями, необходимо форме определить конкретные стили, а для этого нужно её переопределить.
В директории приложения user_app
создадим новый файл forms.py
.
Создадим класс LoginForm
, унаследованный от AuthenticationForm
.
Затем создадим два поля:
Первое будет username
. В нём определим поле символов.
Первым атрибутом будет максимальная длина имени пользователя. По умолчанию в модели пользователя максимальная длина составляет 150 символов, укажем столько же или можете по своему усмотрению указать меньше.
Вторым будет название поля.
Третьим атрибутом будет виджет, в котором определим текстовое поле ввода. Внутри в качестве атрибутов присвоим полю класс, а также укажем текст внутри поля.
Второе поле password
. Также является полем символов.
Первый атрибут такой же - максимальная длина, которая равна 128 символам.
Второй - название поля.
Третьим атрибутом определим виджет, в этот раз это будет поле ввода пароля. Точно также передаём в атрибутах класс и текст внутри поля.
Ниже создаём подкласс Meta
.
Первым полем будет используемая модель пользователя. Поскольку мы пока используем стандартную модель, её и указываем. Если же вы используете расширенную модель пользователя, то указывайте её.
Вторым полем мы указываем поля формы. В нашем случае их всего два, имя пользователя и пароль.
Код:
from django import forms
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.models import User
class LoginForm(AuthenticationForm):
username = forms.CharField(
max_length=150,
label='Имя пользователя',
widget=forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Введите имя пользователя'
})
)
password = forms.CharField(
max_length=128,
label='Пароль',
widget=forms.PasswordInput(attrs={
'class': 'form-control',
'placeholder': 'Введите пароль'
})
)
class Meta:
model = User
fields = ['username', 'password']
Представление страницы авторизации.
Откроем файл views.py
.
Напишем класс CustomLoginView
, унаследованный от LoginView
.
В классе пропишем всего три поля:
authentication_form
- в этом поле указываем класс нашей переопределённой формы.template_name
- в этом поле указываем HTML-файл шаблона.extra_context
- в этом поле указываем дополнительные переменные, передаваемые в шаблон.
Также переопределим метод get_success_url
. В этом методе, воспользовавшись функцией reverse_lazy
указываем на какую страницу перейдёт пользователь после авторизации. Пока у нас нет страницы профиля, будем перенаправлять пользователя на главную страницу.
Код:
from django.contrib.auth.views import LoginView
from django.urls import reverse_lazy
from user_app.forms import LoginForm
class CustomLoginView(LoginView):
authentication_form = LoginForm
template_name = 'user_app/login.html'
extra_context = {'title': 'Авторизация на сайте'}
def get_success_url(self):
return reverse_lazy('blog:index')
Шаблон страницы авторизации.
В директории templates
создадим новую директорию user_app
, а в ней файл login.html
.
В этом файле прописываем тег формы.
Внутри прописываем:
- Тег
csrf_token
. Данный тег обеспечивает защиту формы. - Проверку на наличие не связанных с полями ошибок. Если ошибки есть, выводим их.
- В цикле
for
перебираем поля формы. Выводим название поля и само поле. - Кнопку для отправки формы.
Код:
<form method="post">
{% csrf_token %}
{% if form.non_field_errors %}
<div class="alert alert-danger">
{{ form.non_field_errors }}
</div>
{% endif %}
{% for field in form %}
<p class="form-label">{{ field.label }}</p>
<p>{{ field }}</p>
{% endfor %}
<button type="submit" class="btn btn-outline-success">Войти</button>
</form>
URL-паттерн страницы входа.
Создадим новый файл urls.py
.
Указываем имя приложения и в списке urlpatterns
добавляем путь для страницы авторизации.
Код:
from django.urls import path
from user_app import views
app_name = 'user_app'
urlpatterns = [
path('login/', views.CustomLoginView.as_view(), name='login'),
]
Теперь необходимо добавить приложение в основной файл. Откроем файл urls.py
в директории проекта и добавим новую строку:
path('user/', include('user_app.urls', namespace='user_app')),
Все страницы связанные с пользователем будут начинаться на user
.
Например:
user/login
- авторизацияuser/signup
- регистрацияuser/<username>
- профиль- И так далее....
Выход.
Выход с сайта - очень простой функционал, но есть два варианта его исполнения:
- Если вам не нужна промежуточная страница.
- Если вам нужна промежуточная страница.
Второй вариант, это продолжение первого. В первом случае при выходе пользователя с сайта, он будет переправлен на указанную вами страницу, например, главную. Во втором же варианте, после выхода пользователя с сайта, он попадёт на специальную страницу на которой, например, будет кнопка повторной авторизации или ещё что-то, что вам необходимо.
Рассмотрим оба варианта.
Откроем файл urls.py
в директории приложения. Добавим в список urlpatterns
следующую строку и определим новый импорт:
from django.contrib.auth import views as auth_views
path('logout/', auth_views.LogoutView.as_view(), name='logout'),
Для выхода используем встроенное в Django представление. Определяем URL и название.
На этом месте начинаются различия между первым и вторым вариантом.
Для первого варианта достаточно открыть файл settings.py
и определить новый параметр LOGOUT_REDIRECT_URL
, прописав в нём прямой путь или имя URL-паттерна.
Пример для главной страницы:
LOGOUT_REDIRECT_URL = '/'
LOGOUT_REDIRECT_URL = 'blog:index'
Для второго варианта необходимо в URL-паттерне внутри представления добавить путь к шаблону:
path('logout/', auth_views.LogoutView.as_view(template_name='user_app/logout.html'), name='logout'),
Затем создать этот шаблон с необходимым вам содержимым, например:
{% extends 'blog/base.html' %}
{% block content %}
<div class="form-section container">
<h2>Вы успешно вышли с сайта</h2>
<a href="{% url 'user_app:login' %}">Войти в личный кабинет снова</a>
</div>{% endblock %}
Готово.
Кнопка входа и выхода в шапке сайта.
Остался последний "штрих" - добавить кнопку для входа и выхода в шапку сайта.
При этом, кнопка входа должна быть видна только неавторизованному пользователю, а кнопка выхода авторизованному соответственно.
Откроем файл header.html
и в удобное место добавим следующий код:
{% if user.is_authenticated %}
<div class="dropdown">
<button class="btn btn-primary my-btn dropdown-toggle me-3" type="button"
data-bs-toggle="dropdown" aria-expanded="false">
{{ request.user }}
</button>
<ul class="dropdown-menu dd-color">
<li><a class="dropdown-item dd-item-color" href="{% url 'user_app:logout' %}">Выйти</a></li>
</ul>
</div>
{% else %}
<li class="nav-item">
<a class="nav-link btn btn-primary my-btn me-3"
href="{% url 'user_app:login' %}">Войти</a>
</li>
{% endif %}
Можно запустить Django и протестировать возможность входа и выхода с сайта.
Все статьи