Язык программирования Python

Создание блога на Django. Часть 5: Login

Мы почти подошли к концу этого руководства. В этой части мы займемся логином и регистрацией пользователей. Django предоставляет нам довольно простую и настраиваемую систему аутентификации и авторизации.

Для начала мы должны указать по каким адресам будет осуществляться вход, перенаправление для входа и перенаправление для выхода. Для этого откроем наш файл simple_blog/settings.py и в конце его добавим следующие строки:

LOGIN_URL = '/login/' LOGIN_REDIRECT_URL = '/' LOGOUT_REDIRECT_URL = '/'
Code language: JavaScript (javascript)

Далее мы создадим файл users/url.py и перенесем туда урлы входа и регистрации, которые находились в файле simple_blog/urls.py. Теперь эти два файла будут выглядеть следующим образом:

simple_blog/urls.py

from django.contrib import admin from django.urls import path, include from django.views.generic import TemplateView urlpatterns = [ path('admin/', admin.site.urls), path( route='', view=TemplateView.as_view(template_name='posts/index.html'), name='index' ), path( route='post/my-post.html', view=TemplateView.as_view(template_name='posts/detail.html'), name='detail' ), path( route='about', view=TemplateView.as_view(template_name='about.html'), name='about' ), path('', include(('users.urls', 'users'), namespace='users')),
Code language: JavaScript (javascript)

users/url.py

"""Users URLs.""" # Django from django.urls import path from django.views.generic import TemplateView # View from users import views urlpatterns = [ path( route='login', view=views.LoginView.as_view(), name='login' ), path( route='register', view=views.SignupView.as_view(), name='register' ), path( route='logout/', view=views.LogoutView.as_view(), name='logout' ), path( route='register_completed/', view=TemplateView.as_view(template_name='users/registerok.html'), name='registerok' ), ]
Code language: PHP (php)

Url для входа и регистрации были обновлены и теперь указывают на файл users/views.py и классы, которые обеспечивают их функциональность. Мы также создали путь для полной регистрации, который указывает на шаблон, который мы сейчас создадим, и для выхода из системы.

Далее мы займемся созданием формы регистрации, для чего создадим файл users/forms.py и введем следующие строки кода:

"""User forms.""" # Django from django import forms # Models from django.contrib.auth.models import User from users.models import Profile class SignupForm(forms.Form): """Sign up form.""" email = forms.CharField( min_length=6, max_length=70, widget=forms.EmailInput() ) username = forms.CharField( min_length=6, max_length=70, widget=forms.TextInput() ) password = forms.CharField( max_length=70, widget=forms.PasswordInput() ) password_confirmation = forms.CharField( max_length=70, widget=forms.PasswordInput() ) def clean(self): """Verify password confirmation match.""" data = super().clean() password = data['password'] password_confirmation = data['password_confirmation'] if password != password_confirmation: raise forms.ValidationError('Пароли не совпадают.') return data def save(self): """Create user and profile.""" data = self.cleaned_data data.pop('password_confirmation') user = User.objects.create_user(**data) profile = Profile(user=user) profile.save()

Здесь мы объявляем класс SignupForm, который будет содержать все поля нашей формы. В данном случае мы объявляем все поля типа text. Для email это будет input mail, имя пользователя типа input text, а для паролей типа password.

Затем мы определим функцию clean, которая будет выполняться после отправки формы и будет проверять, совпадает ли пароль с повторным его вводом.

Наконец, мы создадим функцию save, которая удалит поле password_confirmation и сохранит переданную информацию в таблице User and Profile.

Давайте теперь займемся частью представления, для этого откроем файл users/views.py и добавим следующий код:

from django.shortcuts import render from django.views.generic import FormView from django.urls import reverse, reverse_lazy from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth import views as auth_views # Forms from users.forms import SignupForm class SignupView(FormView): """Users sign up view.""" template_name = 'users/register.html' form_class = SignupForm success_url = reverse_lazy('users:registerok') def form_valid(self, form): """Save form data.""" form.save() return super().form_valid(form)

Для регистрации мы используем одно из общих представлений, которые есть в django, в данном случае FormView.

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

В form_class формы, которую мы создали ранее.

success_url будет url для перенаправления, если все прошло успешно.

Наконец, мы используем функцию form_valid для сохранения пользователя, если все прошло успешно.

Изменим шаблон, который мы создали для регистрации в руководстве по дизайну (в предыдущем посте). Для этого откроем файл templates/users/register.html и заменим код на следующий:

{% extends "users/base.html" %} {% block title %}Simple blog - Register{% endblock %} {% block content %} <form class="form-signin" method="POST"> {% csrf_token %} <h1><a href="#" class="title-link">Simple Blog</a></h1> <h1 class="h3 mb-3 font-weight-normal">Register</h1> <label for="id_email" class="sr-only">Email</label> <input type="email" name="email" id="id_email" class="form-control" placeholder="Email" required autofocus> <label for="id_username" class="sr-only">Имя пользователя</label> <input type="text" name="username" id="id_username" class="form-control" placeholder="Имя пользователя" required> <label for="inputPassword" class="sr-only">Пароль</label> <input type="password" name="password" id="id_password" class="form-control" placeholder="Пароль" required> <label for="inputPassword" class="sr-only">Повторите пароль</label> <input type="password" name="password_confirmation" id="id_password_confirmation" class="form-control" placeholder="Повторите пароль" required> <div class="checkbox mb-3"></div> <button class="btn btn-lg btn-primary btn-block" type="submit">Зарегистрироваться</button> {% if form.errors %} {% for field in form %} {% for error in field.errors %} <div class="alert alert-danger"> <strong>{{ error|escape }}</strong> </div> {% endfor %} {% endfor %} {% for error in form.non_field_errors %} <div class="alert alert-danger"> <strong>{{ error|escape }}</strong> </div> {% endfor %} {% endif %} <p class="mt-5 mb-3 text-muted">&copy; Simple Blog {% now "Y" %}</p> </form> {% endblock %}
Code language: HTML, XML (xml)

Изменения, которые мы сделали, заключаются в модификации формы, чтобы django перехватывал поля, которые мы собираемся отправить. Добавляем csrf_token, который нам понадобится для валидации формы. Если при создании пользователя возникнут ошибки, будет показано предупреждение.

Если при создании пользователя все прошло успешно, мы отправим в шаблон уведомление о том, что пользователь создан. Для этого необходимо создать файл templates/users/registerok.html и добавить в него этот код:

{% extends "users/base.html" %} {% block title %}Simple blog - Регистрация завершена{% endblock %} {% block content %} <main role="main" class="container"> <div class="starter-template"> <h1>Пользователь успешно создан</h1> <p class="lead">Если страница не будет перенаправлена в течение 5 секунд, нажмите ссылку<a href="{% url 'users:login' %}">здесь</a></p> </div> </main> <script> setTimeout(function(){ window.location.replace("{% url 'users:login' %}"); }, 5000); </script> {% endblock %}
Code language: HTML, XML (xml)

Здесь мы выводим сообщение и перенаправляем на страницу входа с помощью {% url ‘users:login’ %}, который находится в наших файлах urls.py и генерирует url на основе пространства имен и имени, которые мы добавили в urls.

Для доступа к регистрации мы заходим на эту страницу https://127.0.0.1:8000/register и можем создать пользователя для последующего тестирования.

Теперь, когда у нас есть регистрационная часть, мы приступаем к работе с частью входа в систему. Мы открываем наш файл users/views.py и в конце его добавляем следующие строки:

class LoginView(auth_views.LoginView): """Login view.""" template_name = 'users/login.html' class LogoutView(LoginRequiredMixin, auth_views.LogoutView): """Logout view.""" template_name = 'users/logged_out.html'

Шаблон назначается классу LoginView, а вся логика выполняется Django. В случае с выходом из системы все точно так же, хотя. В этом случае шаблон не нужен, но мы добавляем его (даже если он не существует). На этом часть представления готова.

В завершение откроем файл templates/users/login.html и изменим существующий код на следующий:

{% extends "users/base.html" %} {% block content %} <form method="POST" action="{% url "users:login" %}" class="form-signin"> {% csrf_token %} <h1><a href="#" class="title-link">Simple Blog</a></h1> <h1 class="h3 mb-3 font-weight-normal">Login</h1> <label for="id_username" class="sr-only">Пользователь</label> <input type="text" id="id_username" class="form-control" placeholder="Пользователь" name="username" required autofocus> <label for="id_password" class="sr-only">Пароль</label> <input type="password" id="id_password" class="form-control" placeholder="Пароль" name="password" required> <div class="checkbox mb-3"></div> <button class="btn btn-lg btn-primary btn-block" type="submit">Login</button> {% if form.errors %} {% for field in form %} {% for error in field.errors %} <div class="alert alert-danger"> <strong>{{ error|escape }}</strong> </div> {% endfor %} {% endfor %} {% for error in form.non_field_errors %} <div class="alert alert-danger"> <strong>{{ error|escape }}</strong> </div> {% endfor %} {% endif %} <p class="mt-5 mb-3 text-muted">&copy; Simple Blog {% now "Y" %}</p> </form> {% endblock %}
Code language: HTML, XML (xml)

Как и в шаблоне регистрации, мы добавляем csrf_token и, если есть ошибки, фиксируем их.

Заключение

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *