Создаем в Django страницу регистрации пользователей


05 апреля 2023


Создаем страницу регистрации пользователей Django

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

 

 

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

При регистрации пользователи используют форму, состоящую из нескольких полей. Такая форма уже создана разработчиками Django и называется 'UserCreationForm'. Основная задача такой формы - получить значения, проверить их, а затем занести в базу данных. Например форма проверяет, что пароль введен верно дважды и требования к регистру соблюдены.

Форма строится на модели 'User'. Это может быть важно т.к. вы будете использовать одну и ту же модель, что и для панели администрирования Django.

Создание тестового проекта

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

django-admin startproject testproject
cd .\testproject\
python manage.py startapp testapp

Изменяем переменную 'INSTALLED_APPS' в файле 'testproject/settigs.py' добавляя в нее приложение.

INSTALLED_APPS = [
    ...
    'testapp.apps.TestappConfig',
]

В этом же файле изменяем путь до шаблонов.

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates'],
        ...
    },
]

Прописываем приложение и путь до шаблонов Django

Выполняем миграцию.

python manage.py migrate

Выполняем миграции Django

 

Создание представления

Нам нужно создать вьюшку, которая будет выполнять два действия:

  1. Возвращать пользователю форму 'UserCreationForm', если он только открыл страницу. Это делается через метод 'GET';
  2. Обрабатывать значения, если пользователь уже заполнил форму. Это делается через метод 'POST'.

Самая простая реализация будет выглядеть следующим образом

# testapp/views.py

from django.contrib.auth.forms import UserCreationForm
from django.shortcuts import render

def registration(request):
    if request.method == 'POST':
        form = UserCreationForm(request.POST)
        if form.is_valid():
            form.save()
    else:
        form = UserCreationForm()
    return render(request, 'signup.html', {'form': form})

Создаем view для регистрации пользователей в Django

Проблема предыдущего варианта в том, что после успешного заполнения формы, мы будем продолжать оставаться на той же странице. Чаще всего, после регистрации, пользователь автоматически аутентифицируется и переходит на какую-то страницу. В Django эти действия выполняются через методы authenticate (проверка логина и пароля), login (присоединение пользователя к сессии) и redirect. Пример такого представления.

# testapp/views.py

from django.contrib.auth import login, authenticate
from django.contrib.auth.forms import UserCreationForm
from django.shortcuts import render, redirect

def registration(request):
    if request.method == 'POST':
        form = UserCreationForm(request.POST)
        if form.is_valid():
            form.save()
            # получаем имя пользователя и пароль из формы
            username = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password1')
            # выполняем аутентификацию
            user = authenticate(username=username, password=password)
            login(request, user)
            return redirect('/')
    else:
        form = UserCreationForm()
    return render(request, 'signup.html', {'form': form})

Нам так же нужно казать по какому URL можно будет увидеть форму. Это делается в urls.py:

# testproject/urls.py

from django.contrib import admin
from django.urls import path
from testapp.views import registration

urlpatterns = [
    path('admin/', admin.site.urls),
    path('user/registration/', registration)
]

Прописываем URL для регистрации пользователей Django

 

Создание шаблона

Вьюшка будет возвращать шаблон с формой. Шаблон нужно создать отдельно. Самый простой вариант шаблона с формой - это создание файла по пути 'templates/signup.html' со следующим содержанием.

  <h2>Регистрация</h2>
  <form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Отправить</button>
  </form>

После этого мы можем запустить сервер и увидеть страницу регистрации пользователей.

python manage.py runserver

Просмотр работы формы регистрации пользователей Django

 

Расширение формы с добавлением полей

По умолчанию, для регистрации требуется только часть полей, которые прописаны у модели 'User'. Мы можем расширить их разными путями. Например, мы можем добавить поля для заполнения электронной почты или телефона при регистрации. Что бы это сделать нам нужно создать новую форму на основе 'UserCreationForm'. Форма создается в отдельном файле по пути 'testapp/forms.py'.

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

class SignUpForm(UserCreationForm):
    phone_number = forms.CharField(max_length=15, required=True, help_text='Номер телефона какого-то формата')

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

Отмечу, что форма работает на основе модели 'User'. У этой модели есть поле 'email', но нет поля для телефонного номера. Один из вариантов решения этой задачи - это создание отдельной модели, которая будет относиться к профилю пользователя. Она может хранить информацию о телефоне, дне рождения, поле, и т.д.

# testapp/models.py

from django.db import models
from django.contrib.auth.models import User

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    phone_number = models.CharField(max_length=15)
    birth_date = models.DateField(null=True, blank=True)

Выполняем миграции.

python manage.py makemigrations
python manage.py migrate

Теперь нужно создать представление. Его основное отличие от предыдущих вьюшек в том, что 'phone_number' мы должны сохранять отдельно.

# testapp/views.py

from django.contrib.auth import login, authenticate
from django.shortcuts import render, redirect
from .forms import SignUpForm
from .models import Profile


def registration(request):
    if request.method == 'POST':
        form = SignUpForm(request.POST)
        if form.is_valid():
            user = form.save()
            # сохранение номера
            Profile.objects.create(user=user, phone_number=form.cleaned_data.get('phone_number'))
            raw_password = form.cleaned_data.get('password1')
            user = authenticate(username=user.username, password=raw_password)
            login(request, user)
            return redirect('/')
    else:
        form = SignUpForm()
    return render(request, 'signup.html', {'form': form})

После запуска проекта можно увидеть новые поля.

Изменение формы регистрации пользователей Django

Изменение описание полей формы

Например нам может понадобиться использовать другой язык. Что бы это сделать мы можем изменить переменную 'LANGUAGE_CODE' в файле 'settings.py'. Пример с использованием русского языка.

# testproject/settings.py
...
LANGUAGE_CODE = 'ru-RU'
...

Изменение языка в Django

Описание полей устанавливаются в параметре 'label' и 'help_text'. Так, например, мы можем изменить описание пароля.

class SignUpForm(UserCreationForm):
    phone_number = forms.CharField(
        max_length=15,
        help_text='Номер телефона. Формат +7910...', label='test'
    )
    password1 = forms.CharField(
        label='Password',
        strip=False,
        widget=forms.PasswordInput(attrs={"autocomplete": "new-password"}),
        help_text='Одна большая буква и т.д.',
    )

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

Изменение описания полей формы Django 

 

 

Отправка уведомлений о регистрации и подтверждение

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

Подтверждение регистрации через почту можно сделать самостоятельно или через модуль. Один из самых популярных модулей для этого - 'django-email-verification'.

pip install django-email-verification

После установки добавляем приложение в 'testproject/settings.py', в переменную 'INSTALLED_APPS'.

INSTALLED_APPS = [
    ...
    'django_email_verification',
]

Так же, в 'testproject/settings.py' мы прописываем ряд инструкций.

# функция, которая сделает пользователя активным
# после того, как он перейдет по ссылке
def verified_callback(user):
    user.is_active = True

EMAIL_VERIFIED_CALLBACK = verified_callback

# тема письма
EMAIL_MAIL_SUBJECT = 'Confirm your email'
# шаблон письма в html
EMAIL_MAIL_HTML = 'mail_body.html'
# текстовый шаблон
EMAIL_MAIL_PLAIN = 'mail_body.txt'
# время жизни ссылки
EMAIL_MAIL_TOKEN_LIFE = 60 * 60
# шаблон, который увидят после перехода по ссылке
EMAIL_MAIL_PAGE_TEMPLATE = 'confirm_template.html'
# домен для использования в ссылке
EMAIL_PAGE_DOMAIN = 'http://mydomain.com/'
EMAIL_MULTI_USER = True

# настройки вашего SMTP сервера
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'mymail@gmail.com'
EMAIL_FROM_ADDRESS = 'mymail@gmail.com'
EMAIL_HOST_PASSWORD = 'mYC00lP4ssw0rd'
EMAIL_USE_TLS = True

# используется для тестирования
# выводит письма в консоли
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

Настройки модуля по отправке писем при регистрации Django

Создадим шаблон по пути 'templates/mail_body.html' следующего содержания.

<h2>Пользователь {{ user.username }} - перейдите по ссылке <a href="{{ link }}">тут</a></h2>
<p>Ссылка истечет {{ expiry|time:"TIME_FORMAT" }}</p>

По этому же пути шаблон 'templates/mail_body.txt' с похожим содержанием:

Пользователь {{ user.username }} - перейдите по ссылке {{ link }}
Ссылка истечет {{ expiry|time:"TIME_FORMAT" }}

Шаблоны для отправки писем при регистрации пользователей Django

Еще один шаблон 'templates/confirm_template.html', который увидят после перехода по ссылке.

{% if success %}
{{ user.username }} все ок
{% else %}
Что-то не так
{% endif %}

И изменим вьюшку, где будем делать пользователя неактивным и высылать письмо.

# testapp/views.py

from django.contrib.auth import login, authenticate
from django.shortcuts import render, redirect
from .forms import SignUpForm
from .models import Profile
from django_email_verification import send_email


def registration(request):
    if request.method == 'POST':
        form = SignUpForm(request.POST)
        if form.is_valid():
            user = form.save()
            Profile.objects.create(user=user, phone_number=form.cleaned_data.get('phone_number'))
            raw_password = form.cleaned_data.get('password1')
            user = authenticate(username=user.username, password=raw_password)
            login(request, user)
            # высылаем письмо и делаем его неактивным
            user.is_active = False
            send_email(user)
            return redirect('/')
    else:
        form = SignUpForm()
    return render(request, 'signup.html', {'form': form})

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

# testproject/urls.py

from django.contrib import admin
from django.urls import path, include
from testapp.views import registration
from django_email_verification import urls as email_urls 

urlpatterns = [
    path('admin/', admin.site.urls),
    path('user/registration/', registration),
    path('email/', include(email_urls)),
]

Можно запустить сервер и проверить регистрацию. Т.к. в моем случае использовался 'django.core.mail.backends.console.EmailBackend', который используется для тестирования отправки сообщений, письмо я увижу в консоли. Если перейти по ссылке, то изменится параметр, который отвечает за активность.

Пример работы отправки писем при регистрации пользователей Django

...

Теги: #python #django


Каналы
Telegram FixMyPc Telegram Лента FixMyPC RSS Rss
Популярные тэги
О блоге
Этот блог представляет собой конспекты выученного материала, приобретённого опыта и лучшие практики в системном администрировании и программировании.