LoginView Django позволяет отображать форму входа и обрабатывать действие входа. Мы будем использовать класс LoginView для создания страницы входа для приложения Todo в Python.
Создание и настройка пользовательского приложения для проекта todo
Пользовательское приложение будет иметь следующие функции:
- Войти / Выйти
- Зарегистрироваться
- Сбросить пароль
В этом уроке мы сосредоточимся на функциях входа/выхода из системы.
- Сначала используйте команду startapp для создания приложения пользователя:
django-admin startapp users
- Далее зарегистрируйте приложение пользователя в settings.py проекта:
INSTALLED_APPS = [
#...
'users'
]
- Затем создайте urls.py в приложении пользователя со следующим кодом:
from django.urls import path urlpatterns = []
- После этого включите urls.py приложения пользователя в urls.py проекта:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('todo.urls')),
path('',include('users.urls'))
]
- Наконец, создайте каталог templates и каталог users внутри каталога templates в приложении users для хранения шаблонов.
Создание страницы входа
Ниже определяется класс MyLoginView в файле views.py, который наследуется от класса LoginView:
from django.contrib.auth.views import LoginView
from django.urls import reverse_lazy
from django.contrib import messages
class MyLoginView(LoginView):
redirect_authenticated_user = True
def get_success_url(self):
return reverse_lazy('tasks')
def form_invalid(self, form):
messages.error(self.request,'Invalid username or password')
return self.render_to_response(self.get_context_data(form=form))
Как это работает.
Сначала импортируйте LoginView из django.contrib.auth.views, reverse_lazy из django.urls и messages из django.contrib.
from django.contrib.auth.views import LoginView from django.urls import reverse_lazy from django.contrib import messages
Во-вторых, определите класс MyLoginView, который наследуется от класса LoginView. MyLoginView имеет следующие атрибуты и методы:
- redirect_authenticated_user установлен в True, чтобы указать Django перенаправлять пользователей после успешного входа в систему. По умолчанию redirect_authenticated_user имеет значение False, что отключает перенаправление.
- get_success_url() возвращает URL-адрес для перенаправления после успешного входа пользователя в систему.
- form_invalid() вызывается после неудачной попытки входа. В form_invalid() мы создаем флэш-сообщение и перерисовываем форму входа.
Определение маршрута для страницы входа
Измените файл views.py, чтобы определить маршрут для страницы входа:
from django.urls import path
from .views import MyLoginView
urlpatterns = [
path('login/', MyLoginView.as_view(),name="login"),
]
Как это работает.
Сначала импортируйте класс MyLoginView из views.py:
from .views import MyLoginView
Во-вторых, сопоставьте маршрут login/ с результатом метода as_view() класса MyLoginView.
urlpatterns = [
path('login/', MyLoginView.as_view(),name="login"),
]
Создание шаблона входа
Сначала создайте шаблон login.html в каталоге templates/users со следующим кодом:
{%extends 'base.html'%}
{%block content%}
<div class="center">
<form method="post" class="card" novalidate>
{% csrf_token %}
<h2 class="text-center">Log in to your account</h2>
{% for field in form %}
{{ field.label_tag }}
{{ field }}
{% if field.errors %}
<small>{{ field.errors|striptags }}</small>
{% endif %}
{% endfor %}
<input type="submit" value="Login" class="btn btn-primary full-width">
<hr>
<p class="text-center">Forgot your password <a href="#">Reset Password</a></p>
<p class="text-center">Don't have a account? <a href="#">Join Now</a></p>
</form>
</div>
{%endblock content%}
Если вы откроете URL-адрес для входа:
http://127.0.0.1:8000/login/
Вы увидите следующую форму входа:

Если вы введете действительное имя пользователя и пароль, вы успешно войдете в систему. В противном случае вы получите сообщение о том, что вы ввели недействительное имя пользователя или пароль.
Во-вторых, добавьте LOGIN_URL в settings.py проекта:
LOGIN_URL = 'login'
Если вы попытаетесь получить доступ к странице, требующей входа, Django будет использовать этот LOGIN_URL для перенаправления. Если вы не добавите LOGIN_URL в settings.py, Django будет использовать URL входа по умолчанию, который является accounts/login/.
Создание URL-адреса для выхода из системы
LogoutView выводит пользователя из системы и отображает сообщение. Мы будем использовать LogoutView для создания ссылки выхода.
В отличие от класса LoginView, вы можете использовать класс LogoutView непосредственно в urls.py. Например, вы можете изменить views.py, чтобы создать маршрут для URL выхода:
from django.urls import path
from .views import MyLoginView
from django.contrib.auth.views import LogoutView
urlpatterns = [
path('login/', MyLoginView.as_view(),name="login"),
path('logout/', LogoutView.as_view(next_page="login"),name="logout"),
]
Как это работает.
Сначала импортируйте LogoutView из django.contrib.auth.views:
from django.contrib.auth.views import LogoutView
Во-вторых, сопоставьте URL logout/ с результатом метода as_view() класса LogoutView. Аргумент next_page указывает URL, на который будут перенаправлены пользователи после успешного выхода из системы.
path('logout/', LogoutView.as_view(next_page="login"),name="logout")
Добавление ссылок входа/выхода в заголовок
Если пользователь вошел в систему, заголовок показывает домашнюю страницу, мои задачи, новую задачу и ссылку выхода. После выхода пользователя из системы заголовок показывает домашнюю страницу, ссылку входа и ссылку присоединения сейчас.
Для этого необходимо изменить шаблон base.html проекта следующим образом.
{%load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://copython.ru/{% static"css/style.css' %}" />
<title>Todo List</title>
</head>
<body>
<header class="header">
<div class="container">
<a href="{%url 'home'%}" class="logo">Todo</a>
<nav class="nav">
<a href="{%url 'home'%}"><i class="bi bi-house-fill"></i> Home</a>
{% if request.user.is_authenticated %}
<a href="{% url 'tasks' %}"><i class="bi bi-list-task"></i> My Tasks</a>
<a href="{% url 'task-create' %}"><i class="bi bi-plus-circle"></i> Create Task</a>
<a href="#">Hi {{request.user | title}}</a>
<a href="{% url 'logout' %}" class="btn btn-outline">Logout</a>
{% else %}
<a href="{% url 'login' %}" class="btn btn-outline">Login</a>
<a href="#" class="btn btn-primary">Join Now</a>
{% endif %}
</nav>
</div>
</header>
<main>
<div class="container">
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{message.tags}}">
{{message}}
</div>
{% endfor %}
{% endif %}
{%block content %}
{%endblock content%}
</div>
</main>
<footer class="footer">
<div class="container">
<p>© Copyright {% now "Y" %} by <a href="https://www.pythontutorial.net">Python Tutorial</a></p>
</div>
</footer>
</body>
</html>
Обратите внимание, что если пользователь вошел в систему, request.user.is_authenticated возвращает True. Таким образом, вы можете использовать это свойство для проверки того, вошел ли пользователь в систему или нет.
Если вы не вошли в систему, в навигации вы увидите следующие ссылки:

Однако если вы войдете в систему, вы увидите следующие навигационные ссылки:

Класс LoginRequiredMixin
Хотя вы не вошли в систему, вы все равно можете управлять списком задач, например, просматривать, добавлять, редактировать и удалять задачи. Чтобы защитить эти страницы, вы будете использовать класс LoginRequiredMixin.
Для этого нужно изменить views.py приложения todo и использовать класс LoginRequiredMixin следующим образом:
from django.shortcuts import render
from django.views.generic.list import ListView
from django.views.generic.detail import DetailView
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.contrib import messages
from django.urls import reverse_lazy
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import Task
class TaskDelete(LoginRequiredMixin, DeleteView):
model = Task
context_object_name="task"
success_url = reverse_lazy('tasks')
def form_valid(self, form):
messages.success(self.request, "The task was deleted successfully.")
return super(TaskDelete,self).form_valid(form)
class TaskUpdate(LoginRequiredMixin, UpdateView):
model = Task
fields = ['title','description','completed']
success_url = reverse_lazy('tasks')
def form_valid(self, form):
messages.success(self.request, "The task was updated successfully.")
return super(TaskUpdate,self).form_valid(form)
class TaskCreate(LoginRequiredMixin, CreateView):
model = Task
fields = ['title','description','completed']
success_url = reverse_lazy('tasks')
def form_valid(self, form):
form.instance.user = self.request.user
messages.success(self.request, "The task was created successfully.")
return super(TaskCreate,self).form_valid(form)
class TaskDetail(LoginRequiredMixin, DetailView):
model = Task
context_object_name="task"
class TaskList(LoginRequiredMixin,ListView):
model = Task
context_object_name="tasks"
def home(request):
return render(request,'home.html')
Если вы не вошли в систему и попытались получить доступ к защищенной странице, Django перенаправит вас на страницу входа. Например:
http://127.0.0.1:8000/task/create
Django перенаправит вас на страницу входа, используя LOGIN_URL, настроенный в settings.py:
http://127.0.0.1:8000/login/?next=/task/create/
