В этой статье будет рассказано, как разрешить функции регистрации, входа и выхода пользователей на сайте, созданном с использованием Django Web Framework.

Прежде чем мы начнем, виртуальная среда называется env, проект Django - mysite, а приложение - main.

Регистрация пользователя

Как вы могли заметить, Django поставляется со встроенной формой регистрации пользователя. Нам просто нужно настроить его в соответствии с нашими потребностями (т.е. получить адрес электронной почты при регистрации).

Создайте регистрационную форму

env ›mysite› ​​main ›(Новый файл) forms.py

from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User


# Create your forms here.

class NewUserForm(UserCreationForm):
	email = forms.EmailField(required=True)

	class Meta:
		model = User
		fields = ("username", "email", "password1", "password2")

	def save(self, commit=True):
		user = super(NewUserForm, self).save(commit=False)
		user.email = self.cleaned_data['email']
		if commit:
			user.save()
		return user

Django поставляется с предварительно созданной регистрационной формой под названием UserCreationForm, которая подключается к предварительно созданной модели User. Однако UserCreationForm требует только имя пользователя и пароль (пароль1 - это начальный пароль, а пароль2 - подтверждение пароля).

Чтобы настроить предварительно созданную форму, сначала создайте новый файл с именем forms.py в каталоге приложения.

Этот новый файл создается в том же каталоге, что и models.py и views.py.

Затем вызовите UserCreationForm в новом классе с именем NewUserForm и добавьте еще одно поле с именем email. Сохраните электронное письмо для пользователя.

При необходимости добавьте дополнительные поля в UserCreationForm.

Создайте файл register.html

env ›mysite› ​​main ›templates› main ›(Новый файл) register.html

{% extends "main/header.html" %}

{% block content %} 

{% load crispy_forms_tags %}         

<!--Register--> 
<div class="container py-5">
	<h1>Register</h1>
	<form method="POST">
		{% csrf_token %}
		{{ register_form|crispy }}                    
		<button class="btn btn-primary" type="submit">Register</button>
	</form>
	<p class="text-center">If you already have an account, <a href="/login">login</a> instead.</p>
</div>

{% endblock %}

Затем создайте HTML-шаблон для регистрационной формы. Мы назовем этот шаблон register.html.

Форма использует Bootstrap и Django crispy-forms для некоторого добавленного CSS.

Он также расширяет header.html из раздела Как использовать расширяет и включать теги шаблона Django.

Добавьте в приложение регистрационный URL

env ›mysite› ​​main ›urls.py

from django.urls import path
from . import views

app_name = "main"   


urlpatterns = [
    path("", views.homepage, name="homepage"),
    ...
    path("register", views.register_request, name="register")
]

Теперь добавьте путь регистрации к URL-адресам приложения, чтобы мы могли ссылаться на него в представлениях.

URL-адреса также включают шаблон URL-адреса домашней страницы, который можно найти в Шпаргалке для начинающих веб-приложений Django.

Добавьте функцию регистрации в представления

env ›mysite› ​​main ›views.py

from django.shortcuts import  render, redirect
from .forms import NewUserForm
from django.contrib.auth import login
from django.contrib import messages #import messages

def register_request(request):
	if request.method == "POST":
		form = NewUserForm(request.POST)
		if form.is_valid():
			user = form.save()
			login(request, user)
			messages.success(request, "Registration successful." )
			return redirect("main:homepage")
		messages.error(request, "Unsuccessful registration. Invalid information.")
	form = NewUserForm
	return render (request=request, template_name="main/register.html", context={"register_form":form})

Импортируйте NewUserForm из forms.py и login из django.contrib.auth. Затем напишите новую функцию просмотра с именем register_request.

Внутри функции есть два оператора if / else. Первый проверяет, отправляется ли форма, а второй проверяет, действительна ли форма. Если оба верны, то информация формы сохраняется под пользователем, пользователь входит в систему, и пользователь перенаправляется на домашнюю страницу с сообщением об успешном завершении.

В противном случае, если форма недействительна, отображается сообщение об ошибке. Но если запрос не является POST-запросом, то есть первый оператор if вернул false, отобразить пустую форму в шаблоне регистра.

Обратите внимание, что если вы хотите добавлять сообщения в свой проект Django, вы должны включить Messages Framework и импортировать сообщения вверху views.py.

Протестируйте функцию регистрации пользователя

После завершения функции регистрации вы можете перейти к URL-адресу регистрации http://127.0.0.1:8000/register в окне браузера.

Создайте учетную запись testuser.

Если все сделано правильно, вы будете перенаправлены на главную страницу с сообщением об успешном завершении регистрации.

Теперь давайте проверим информацию о пользователе в администрации Django.

Создайте суперпользователя

Терминал / командная строка

(env) C:\Users\Owner\Desktop\Code\env\mysite>py manage.py createsuperuser
Username (leave blank to use 'owner'): owner
Email address: 
Password: *****
Password (again): *****
Superuser created successfully.

(env) C:\Users\Owner\Desktop\Code\env\mysite>py manage.py runserver

Если вы еще этого не сделали, создайте учетную запись суперпользователя, чтобы получить доступ к администрированию Django. Мы собираемся проверить, правильно ли был добавлен пользователь в базу данных.

Запустите команду py manage.py createsuperuser в командной строке Windows и python3 manage.py createsuperuser в терминале Mac. Затем введите логин и пароль.

Проверьте, есть ли пользователь в списке администратора Django

Перейдите по URL-адресу http://127.0.0.1:8000/admin/, где вы увидите логин администратора Django.

Если вы все еще вошли в систему как testuser, вы получите предупреждающее сообщение «Вы аутентифицированы как testuser1, но не авторизованы для доступа к этой странице. Хотите войти в другую учетную запись? ».

Да, конечно.

Войдите в систему с учетной записью суперпользователя и нажмите «Пользователи». Там вы должны увидеть список всех имен пользователей и адресов электронной почты, а также статус их сотрудников.

Логин пользователя

Теперь вы, возможно, заметили, что созданная нами функция представлений автоматически входила в систему при создании учетной записи. Мы хотим, чтобы у пользователя была возможность свободно входить в систему. Итак, нам нужны шаблон входа в систему, URL-адрес и функция просмотров.

Создайте файл login.html

env ›mysite› ​​main ›templates› main ›(новый файл) login.html

{% extends "main/header.html" %}

{% block content %}      

{% load crispy_forms_tags %}

<!--Login--> 
<div class="container py-5">
  <h1>Login</h1>
  <form method="POST">
    {% csrf_token %}
    {{ login_form|crispy }}
    <button class="btn btn-primary" type="submit">Login</button>
  </form>
  <p class="text-center">Don't have an account? <a href="/register">Create an account</a>.</p>
</div>

{% endfor %}

Базовая структура HTML-шаблона аналогична регистровому HTML. Единственные отличия - это форма и ссылка внизу.

Добавить URL для входа

env ›mysite› ​​main ›urls.py

from django.urls import path
from . import views

app_name = "main"   


urlpatterns = [
    path("", views.homepage, name="homepage"),
    ...
    path("register", views.register_request, name="register"),
    path("login", views.login_request, name="login")
]

Добавьте путь для входа в URL-адреса.

Добавьте функцию входа в представления

env ›mysite› ​​main ›views.py

from django.shortcuts import  render, redirect
from .forms import NewUserForm
from django.contrib.auth import login, authenticate #add this
from django.contrib import messages
from django.contrib.auth.forms import AuthenticationForm #add this

def register_request(request):
	...

def login_request(request):
	if request.method == "POST":
		form = AuthenticationForm(request, data=request.POST)
		if form.is_valid():
			username = form.cleaned_data.get('username')
			password = form.cleaned_data.get('password')
			user = authenticate(username=username, password=password)
			if user is not None:
				login(request, user)
				messages.info(request, f"You are now logged in as {username}.")
				return redirect("main:homepage")
			else:
				messages.error(request,"Invalid username or password.")
		else:
			messages.error(request,"Invalid username or password.")
	form = AuthenticationForm()
	return render(request=request, template_name="main/login.html", context={"login_form":form})

Теперь вернитесь к views.py и добавьте authenticate в список импорта формы django.contrib.auth, затем импортируйте AuthenticationForm из django.contrib.auth.forms в верхней части файла.

AuthenticationForm - это предварительно созданная форма Django для входа пользователя в систему.

Чтобы написать функцию входа в систему, добавьте оператор if / else, который использует функцию Django authenticate(). Эта функция используется для проверки учетных данных пользователя (имени пользователя и пароля) и возврата правильного объекта User, хранящегося в серверной части.

Если серверная часть аутентифицировала учетные данные, функция запустит Django login() для входа в систему для аутентифицированного пользователя. В противном случае, если пользователь не аутентифицирован, он возвращает пользователю сообщение о том, что он ввел неверное имя пользователя или пароль.

Второй оператор else: если форма недействительна, она возвращает аналогичное сообщение об ошибке.

Последний оператор else: если запрос не является POST, вернуть пустую форму в HTML-шаблоне входа в систему.

Проверьте функциональность входа пользователя

Теперь перейдите по URL-адресу входа, http://127.0.0.1:8000/login, и войдите в свой testuser.

Вы получите сообщение об успешном выполнении и войдете в систему, если ввели правильное имя пользователя и пароль.

БОНУС: разрешите регистрацию через учетные записи социальных сетей (например, Facebook, Google, Twitter…)

На данный момент вход в систему доступен только через встроенную в Django UserCreationForm, но вы можете легко использовать django-alluth для быстрой обработки и создания потоков регистрации. Это означает, что пользователи могут создать учетную запись пользователя, используя свои учетные записи в социальных сетях. Вы можете следовать этому руководству здесь.

Выход пользователя

Последнее, что нам нужно сделать, - это выйти из системы. Мы разместим ссылку для выхода из системы на панели навигации, но она будет видна пользователям только в том случае, если они аутентифицированы (т.е. они вошли в систему).

<!--Navbar-->
<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <a class="navbar-brand" href="#">Navbar</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarText" aria-controls="navbarText" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="collapse navbar-collapse" id="navbarText">
    <ul class="navbar-nav mr-auto">
      {% if user.is_authenticated %}
      
      <li class="nav-item">
        <a class="nav-link" href="/logout">Logout</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Welcome, {{user.username}}</a>
      </li>

      {% else %}

      <li class="nav-item">
        <a class="nav-link" href="/login">Login</a>
      </li>

      {% endif %}
    </ul>
  </div>
</nav>

В переменной {{ user }} шаблона Django хранится текущий авторизованный пользователь, и его разрешения доступны в контексте шаблона.

Все, что нам нужно сделать, это добавить оператор if / else, который, если пользователь аутентифицирован, показывает ссылку для выхода и его имя пользователя, иначе показывает ссылку для входа.

Это базовая панель навигации из документации Bootstrap. Если вы хотите настроить его дальше, обратитесь к статье 10 пользовательских панелей навигации Bootstrap.

Добавить URL для выхода

env ›mysite› ​​main ›urls.py

from django.urls import path
from . import views

app_name = "main"   


urlpatterns = [
    path("", views.homepage, name="homepage"),
    ...
    path("register", views.register_request, name="register"),
    path("login", views.login_request, name="login"),
    path("logout", views.logout_request, name= "logout"),
]

Теперь добавьте URL-путь выхода из системы к URL-адресам приложения.

Добавить функцию выхода

env ›mysite› ​​main ›views.py

from django.shortcuts import  render, redirect
from .forms import NewUserForm
from django.contrib.auth import login, authenticate, logout #add this
from django.contrib import messages
from django.contrib.auth.forms import AuthenticationForm

def register_request(request):
	...

def login_request(request):
	...

def logout_request(request):
	logout(request)
	messages.info(request, "You have successfully logged out.") 
	return redirect("main:homepage")

Наконец, добавьте в файл представлений функцию выхода из системы. Функция The logout_request использует Django function logout() для выхода пользователя из своей учетной записи и перенаправления его на домашнюю страницу при запросе URL-адреса выхода.

Проверьте функцию выхода пользователя из системы

Зайдите в окно браузера и перезагрузите страницу.

Войдите снова, если вам нужно.

Рядом с текстом приветствия пользователя должна быть панель навигации со ссылкой для выхода.

Щелкните ссылку выхода, и домашняя страница должна перезагрузиться, показывая сообщение о выходе, но отображать только ссылку для входа.

Что произойдет, если пользователь забудет свой пароль?

Последнее, о чем нужно думать, - это сброс пароля пользователя.

Django также обрабатывает эту функцию, используя свою систему аутентификации.

Если вы хотите узнать, как разрешить пользователям отправлять самим себе пароль для сброса, следуйте руководству Сброс паролей пользователей в Django.

Шаблоны входа в Django + Bootstrap

Если вы хотите дополнительно настроить эти формы регистрации и входа, ознакомьтесь с 14 пользовательскими формами входа в систему.

Устранение возможных ошибок

Страница не найдена (404) / не найдена

Если вы получаете сообщение об ошибке Page not found (404) при переходе к http://127.0.0.1:8000/register, убедитесь, что register добавлен в urls.py.

env ›mysite› ​​main ›urls.py

from django.urls import path
from . import views

app_name = "main"   


urlpatterns = [
    path("", views.homepage, name="homepage"),
    ...
    path("register", views.register_request, name="register"),
]

Перейдите в urls.py и убедитесь, что путь к регистру, связанный с функцией просмотра, добавлен.

Страница не найдена (404) / сообщение не найдено

Если вы создаете путь к регистру с косой чертой в конце, а затем решите удалить косую черту, ваш браузер продолжит поиск кэшированного пути с завершающей косой чертой.

Чтобы исправить это, у вас есть два варианта:

(1) Измените путь URL-адреса, чтобы он соответствовал запрошенному

На желтой странице Django указан текущий запрошенный путь.

«Текущий путь« register / »действительно соответствует любому из тезисов (URL-адреса, перечисленные выше)».

env ›mysite› ​​main ›urls.py

from django.urls import path
from . import views

app_name = "main"   


urlpatterns = [
    path("", views.homepage, name="homepage"),
    ...
    path("register/", views.register_request, name="register"),
]

Перейдите к urls.py и добавьте точный путь, указанный в ошибке, в данном случае путь к регистру с косой чертой в конце.

Сохраните файл, и ошибка больше не возникнет.

(2) Очистите кеш браузера.

Второй вариант - зайти в историю браузера и удалить кешированные данные.

TemplatSyntaxError в / register

Если вы получаете синтаксическую ошибку шаблона с указанием 'crispy_forms_tags' is not registered tag library, вам необходимо убедиться, что django-crispy-forms установлен правильно.

Первоначально опубликовано на https://www.ordinarycoders.com.