До этого мы уже рассмотрели, как добавить логин на сайт.
В этой заметке мы также будем использовать модель и прочий код из предыдущей заметки.
Однако, для логина там мы использовали пользователя, созданного через команду python3 ./manage.py createsuperuser
.
Этот способ имеет ряд недостатков:
- Все созданные пользователи имеют максимальные права доступа.
- Для добавления каждого пользователя потребуется внимание и время администратора файла.
- Данный способ довольно неудобен - ведь каждый раз нужно будет переходить в консоль сервера, на котором запущен 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.