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

Пользователи и их создание в Django - своя регистрация на сайте

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

До этого мы уже рассмотрели, как добавить логин на сайт. В этой заметке мы также будем использовать модель и прочий код из предыдущей заметки. Однако, для логина там мы использовали пользователя, созданного через команду python3 ./manage.py createsuperuser. Этот способ имеет ряд недостатков:

  1. Все созданные пользователи имеют максимальные права доступа.
  2. Для добавления каждого пользователя потребуется внимание и время администратора файла.
  3. Данный способ довольно неудобен - ведь каждый раз нужно будет переходить в консоль сервера, на котором запущен Django сайт.

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

Для начала разберёмся, как создаётся пользователь. Основной метод для создания пользователя в Django - метод create_user класса django.contrib.auth.models.UserManager. Чтобы его использовать, запустим django-shell стандартной командой:

>python ./manage.py shell
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul  8 2019, 19:29:22) [MSC v.1916 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from user.models import User
>>> >>> new_user = User.objects.create_user('test_user', 'email@example.com', 's3cr3t')
>>> new_user.password
'pbkdf2_sha256$260000$4etoAyRE2...zQU7/0='
>>>

То есть, благодаря данному методу мы можем задать стартовые параметры пользователя. При этом пароль будет зашифрован. Пользователь не будет иметь сверх-прав: ни superuser, ни stuff - ни администратор, ни менеджер. Используя данный метод, мы можем автоматизировать создание пользователей на сайте через метод или shell. Однако, это не лучший способ.

Да, с create_user мы используем готовые средства Django для работы с моделью. Но контроллер придётся написать самому. Мы уже видели стандартный Django-вский контроллер для логина - django.contrib.auth.views.LoginView. Аналогичного контроллера для регистрации нет. Поэтому напишем свой. Начнём с определения маршрута в user/urls.py:

from django.urls import path
from .views import UserLoginView, SignupView  # Добавили импорт view

app_name = 'user'

urlpatterns = [
    path(r'login/', UserLoginView.as_view(), name='login'),
    path(r'signup/', SignupView.as_view(), name='signup'),  # добавляем связку маршрута со view
]

Теперь создадим соответствующий view (в терминах Django, а для всего остального мира - контроллер) в файле user/views.py:

...
from django.contrib.auth import login
from django.views.generic import FormView
from django.http import HttpResponseRedirect
from django.urls import reverse

from .forms import LoginForm, SignupForm
from .models import User

...

class SignupView(FormView):
    template_name = 'user/signup.html'
    form_class = SignupForm

    def form_valid(self, form):
        username = form.cleaned_data['username']
        email = form.cleaned_data['email']
        raw_password = form.cleaned_data['password1']
        user = User.objects.create_user(username, email, raw_password)
        login(self.request, user)
        return HttpResponseRedirect(reverse('index'))

Используем Class Based View - FormView для того, чтобы не писать лишний код для обработки POST/GET и валидации формы. Форма у нас будет user.forms.SignupForm - её мы скоро также опишем, она не сложная. А шаблон для страницы регистрации - user/signup.html - он также не сложный, минимально отличается от user/login.html.

После уже известного нам метода create_user мы видим вызов функции login - привязывает сессию текущего пользователя к зарегистрированному у нас пользователю. И потом переадресуем на главную страницу.

Сама форма лежит у нас в user/forms.py и, как и обещал, довольно простая - мы переопределяем django.contrib.auth.forms.UserCreationForm, чтобы использовалась наша модель пользователя, а не из django.contrib.auth:

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

from .models import User

...

class SignupForm(UserCreationForm):
    class Meta:
        model = User
        fields = ("username", "email")
        field_classes = {'username': UsernameField}

А шаблон user/signup.html отличается от user/login.html только заголовком (и оформлением, если вы захотите что-то поменять):

{% extends  'layout/default.html' %}

{% block content %}
<div class="box">
    <h4 class="form-header">Регистрация в системе</h4>

    <form method="post">
        {% csrf_token %}
        <input type="hidden" name="next" value="{{ next }}">

        {{ form }}

        <button type="submit" class="btn btn-primary btn-block">Войти</button>
    </form>
</div>
{% endblock %}

Теперь по указанному URL пользователь может зарегистрироваться на нашем сайте. До сих пор есть определённые проблемы с данным способом: хакер может создать миллионы пользователей, логин также не защищён от перебора, нет проверки email и т.д. Но всё можно доделать, настроить. В данной же заметке мы только рассмтриваем, как добавить простую регистрацию на сайте.

Если интересно, что дальше - читайте рубрику Django.

Также может быть вам интересно:

Как на Bash посчитать число строк в проекте (директории)

Ниже будет представлен однострочник, решающий данную задачу на Bash + пошаговое описание его работы.

Читать »

Разграничение прав доступа на Django сайте

Почти на любом веб-сайте необходимо разделять пользователей на группы и предоставлять им разные возможности. В Django есть довольно серьёзная система прав доступа для пользователей - давайте её рассмотрим!

Читать »
Фото Python: Встроенные типы данных (list, set, dict, etc)

Python: Встроенные типы данных (list, set, dict, etc)

В Python есть множество встроенных типов данных. Их использование значительно упрощает жизнь и ускоряет разработку программных продуктов.

Фото Python: типы данных, переменные, логическое ветвление и циклы

Python: типы данных, переменные, логическое ветвление и циклы

Первая часть заметок о Python. О базовых типах, переменных, ветвлении и циклах.

Фото Как сделать свою middleware в Django (с примерами)

Как сделать свою middleware в Django (с примерами)

Middleware или "промежуточное программное обеспечение" - элегантный способ установить общие правила обработки запросов и ответов приложения. Давайте напишем парочку middleware, чтобы понять, как они работают.

Фото Как настроить отправку почты из Django

Как настроить отправку почты из Django

Письма об ошибках, отчёты на почту, восстановление паролей - всё это полезно при работе с сайтом. Django предоставляет удобный способ это сделать с минимумом настроек!

Фото Новый синтаксис старой команды with в Python 3.10

Новый синтаксис старой команды with в Python 3.10

Как же долго моё чувство прекрасного страдало… Но в Python 3.10 появился новый парсер синтаксических конструкций Python!

Фото Добавляем постраничную пагинацию на Django сайт

Добавляем постраничную пагинацию на Django сайт

На сайтах часто встречаются многостраничные объекты: список товаров, список заметок и т.д. Поэтому важно уметь добавить навигацию по страницам на Django-проекте.

Фото Новый оператор match-case в Python

Новый оператор match-case в Python

В новой версии Python (3.10) появится новый оператор. Новый оператор сопоставления по шаблону (match-case).

Фото Нет слов, одни... однострочники

Нет слов, одни... однострочники

На днях вышел пост со списком полезных однострочников для JavaScript программистов. Памятуя Perl-овую молодость, заглянул туда.