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

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

ПрограммыНастройкиКодPythonWebDjangoБезопасность

До этого мы уже рассмотрели, как добавить логин на сайт. В этой заметке мы также будем использовать модель и прочий код из предыдущей заметки. Однако, для логина там мы использовали пользователя, созданного через команду 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 посчитать число строк в проекте (директории)

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

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

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

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