Django LoginView в Python — создание страницы входа

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/

Оцените статью
Справочник Python