Создание сайта на Django: Урок 24, регистрация, аутентификация пользователей
avatar
7 | (offline)
❤️‍🔥Notehunter Developer
Добавлено:
Категория: Руководства «Django»
Комментариев: 0

Авторизация и регистрация в Django

Django уже предоставляет встроенную систему django.contrib.auth. Мы будем пользоваться ей от части в нашем приложении "system". 

Если вы используете такую же структуру папок, как я, то в папке modules/system/views я создам файл для представлений системы аутентификации: authenticated.py. Тоже самое я сделаю в папке modules/system/forms.

А теперь давайте создадим форму регистрации пользователя:

modules/system/forms/authenticated.py

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


class UserRegisterForm(UserCreationForm):
    """
    Переопределенная форма регистрации пользователей
    """

    class Meta(UserCreationForm.Meta):
        fields = UserCreationForm.Meta.fields + ('email', 'first_name', 'last_name')

    def clean_email(self):
        """
        Проверка email на уникальность
        """
        email = self.cleaned_data.get('email')
        username = self.cleaned_data.get('username')
        if email and User.objects.filter(email=email).exclude(username=username).exists():
            raise forms.ValidationError('Email адрес должен быть уникальным')
        return email

    def __init__(self, *args, **kwargs):
        """
        Обновление стилей формы регистрации
        """
        super().__init__(*args, **kwargs)
        for field in self.fields:
            self.fields['username'].widget.attrs.update({"placeholder": 'Придумайте логин'})
            self.fields['email'].widget.attrs.update({"placeholder": 'Введите ваш email'})
            self.fields['first_name'].widget.attrs.update({"placeholder": 'Ваше имя'})
            self.fields["last_name"].widget.attrs.update({"placeholder": 'Ваша фамилия'})
            self.fields['password1'].widget.attrs.update({"placeholder": 'Придумайте свой пароль'})
            self.fields['password2'].widget.attrs.update({"placeholder": 'Повторите придуманный пароль'})
            self.fields[field].widget.attrs.update({"class": "form-control", "autocomplete": "off"})

Пояснения:

  • Я наследуюсь от встроенной формы Django: UserCreationForm, добавляю ей необходимые новые поля, такие как email, first_name, last_name. Задаю bootstrap стили и placeholder's.
  • Также я добавляю метод def clean_email для проверки на уникальность введенного email. Если email зарегистрирован уже в системе, второй раз его не получится использовать.

Далее я создам представление для нашей формы регистрации:

modules/system/views/authenticated.py

from django.contrib.messages.views import SuccessMessageMixin
from django.urls import reverse_lazy
from django.views.generic import CreateView

from modules.blog.forms.authenticated import UserRegisterForm


class RegisterCreateView(SuccessMessageMixin, CreateView):
    """
    Представление регистрации на сайте с формой регистрации
    """
    form_class = UserRegisterForm
    success_url = reverse_lazy('home')
    template_name = 'modules/system/authenticated/register.html'
    success_message = 'Вы успешно зарегистрировались. Можете войти на сайт!'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['title'] = 'Регистрация на сайте'
        return context

Пояснения:

  • Я использую представление CreateView.
  • Нашу форму UserRegisterForm 
  • При успешной регистрации отправляю пользователя на главную страницу 
  • Использую миксин SuccessMessageMixin для вывода сообщения об успешном завершении регистрации

Напоминаю, если используете ту же структуру папок, то не забываем про __init__.py во views и forms

modules/system/forms/__init__.py

from modules.system.forms.authenticated import *
from modules.system.forms.profiles import *

__all__ = '__all__'

modules/system/views/__init__.py

from modules.system.views.profiles import *
from modules.system.views.authenticated import *

__all__ = '__all__'

Добавляем в urls.py наше новое представление:

from django.urls import path

from modules.system.views import ProfileView, ProfileEditView, RegisterCreateView

urlpatterns = [
    path('user/edit/', ProfileEditView.as_view(), name='profile-edit'),
    path('user/<str:slug>/', ProfileView.as_view(), name='profile'),
    path('register/', RegisterCreateView.as_view(), name='register'),
]

И создаем нужный шаблон с следующей формой:

templates/modules/system/authenticated/register.html

{% extends 'main.html' %}

{% block content %}
    <div class="card mb-3 border-0 nth-shadow">
        <div class="card-body">
            <div class="card-title nth-card-title">
                <h4>Регистрация на сайте</h4>
            </div>
            <form method="post" action="{% url 'register' %}" enctype="multipart/form-data">
                {% csrf_token %}
                {{ form.as_p }}
                <button type="submit" class="btn btn-dark mt-2">Зарегистрироваться</button>
            </form>
        </div>
    </div>
{% endblock %}

Пояснения:

  • Оформил все в Bootstrap
  • Обязательно action="{% url 'register' %}" на наше представление

Давайте проверим, как работает регистрация:

Попробую получить ограничение на email:

И регистрируемся:

После успешной регистрации нас перебрасывает на главную с сообщение об успешной регистрации.

Теперь давайте создадим форму для авторизации на сайте:

modules/system/forms/authenticated.py

from django.contrib.auth.forms import UserCreationForm, AuthenticationForm

class UserLoginForm(AuthenticationForm):
    """
    Форма авторизации на сайте
    """

    def __init__(self, *args, **kwargs):
        """
        Обновление стилей формы регистрации
        """
        super().__init__(*args, **kwargs)
        for field in self.fields:
            self.fields['username'].widget.attrs['placeholder'] = 'Введите ваш логин'
            self.fields['password'].widget.attrs['placeholder'] = 'Введите ваш пароль'
            self.fields['username'].label = 'Логин'
            self.fields[field].widget.attrs.update({
                'class': 'form-control',
                'autocomplete': 'off'
            })

Пояснения:

  • В этой форме я наследуюсь от стандартной django формы AuthenticationForm.
  • Задаю стили и на этом все.

Создадим необходимое представление для авторизации:

modules/system/views/authenticated.py

from django.contrib.auth.views import LoginView

class UserLoginView(SuccessMessageMixin, LoginView):
    """
    Авторизация на сайте
    """
    form_class = UserLoginForm
    template_name = 'modules/system/authenticated/login.html'
    next_page = 'home'
    success_message = 'Добро пожаловать на сайт!'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['title'] = 'Авторизация на сайте'
        return context

Пояснения:

  • Наследуемся от встроенного представления LoginView, изменяя параметры next_page, form_class, template_name на свои.
  • Добавляем миксин для уведомления.

Добавим ссылку на авторизацию:

modules/system/urls.py

from django.urls import path

from modules.system.views import ProfileView, ProfileEditView, RegisterCreateView, UserLoginView

urlpatterns = [
    path('user/edit/', ProfileEditView.as_view(), name='profile-edit'),
    path('user/<str:slug>/', ProfileView.as_view(), name='profile'),
    path('register/', RegisterCreateView.as_view(), name='register'),
    path('login/', UserLoginView.as_view(), name='login')
]

Создадим шаблон:

templates/modules/system/authenticated/login.html

{% extends 'main.html' %}

{% block content %}
    <div class="card mb-3 border-0 nth-shadow">
        <div class="card-body">
            <div class="card-title nth-card-title">
                <h4>Авторизация на сайте</h4>
            </div>
            <form method="post" action="{% url 'login' %}">
                {% csrf_token %}
                {{ form.as_p }}
                <div class="d-grid gap-2 d-md-block mt-2">
                <button type="submit" class="btn btn-dark">Авторизоваться</button>
             </div>
            </form>
        </div>
    </div>
{% endblock %}

Отлично, давайте я попробую войти в аккаунт:

При нажатии на кнопку авторизоваться:

Отлично, я вошел в свой зарегистрированный аккаунт. 

В следующем уроке мы создадим форму восстановления пароля и изменения пароля в профиле.

Комментарии к статье 0
Комментариев нет
Форма добавления комментария (необходима регистрация)