Программы
Пользователи и их создание в 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 есть довольно серьёзная система прав доступа для пользователей - давайте её рассмотрим!

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

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

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

Фото Добавляем поддержку медиа-файлов в Django проект

Добавляем поддержку медиа-файлов в Django проект

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

Фото Настройка журналирования (логирования) в Python с примерами

Настройка журналирования (логирования) в Python с примерами

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

Фото Шаблон разработки ПО — Model View Controller (MVC)

Шаблон разработки ПО — Model View Controller (MVC)

MVC - один из самых распространённых архитектурных шаблонов разработки. Часто используется в различных фреймворках. В том числе и в Django.

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

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

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

Фото Добавляем переменные в контекст Django шаблонов (свой контекст-процессор)

Добавляем переменные в контекст Django шаблонов (свой контекст-процессор)

В Django вы можете передавать данные в шаблоны посредством контекстов. Контекст передаётся из контроллера (view в терминах Django), однако, если одни и те же данные нужны в разных местах, лучше сделать свой контекст-процессор.

Фото Пример своей консольной команды в Django проекте

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

Если вы работали с Django проектом, то, скорее всего, запускали команды из консоли (manage.py). В Django есть простой способ писать свои команды для управления проектом.

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

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

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