Представления
В каталоге accounts открываем файл views.py и наполняем следующим:
from django.shortcuts import render, redirect
from django.contrib.auth import login
from django.conf import settings
from . import forms
from .utils import Vcode
from .decorators import anonymous_required
@anonymous_required
def join_view(request):
form = forms.JoinForm(request.POST or None)
if form.is_valid():
form.save(request=request)
return redirect('accounts:join_confirm')
return render(request, 'accounts/join.html', {
'form': form,
})
@anonymous_required
def join_confirm_view(request, code):
status = 'waiting'
if code:
vcode = Vcode(request)
if vcode.is_valid(code, 'join'):
status = 'success'
user = vcode.get_inactive_user()
# активируем и авторизуем пользователя
user.is_active = True
user.save()
# привязываем вручную бэкенд авторизации для того чтоб не проводить доп. аутентификацию
login(request, user, settings.ACCOUNTS_EMAILBACKEND)
else:
status = 'invalid'
return render(request, 'accounts/join_confirm.html', {
'status': status,
})
@anonymous_required
def join_resend_view(request):
form = forms.JoinResendForm(request.POST or None)
if form.is_valid():
form.send_vcode(request)
return redirect('accounts:join_confirm')
return render(request, 'accounts/join_resend.html', {
'form': form,
})
Представление join_view отображает форму регистрации пользователя. Проверяет заполненную форму на наличие ошибок, и в случае обнаружение таковых выводит шаблон с рекомендациями к исправлению.
Если форма заполнена верно, переходим к сохранению и перенаправляем пользователя на страницу подтверждения.
Затем join_confirm_view берет на себе две задачи: сообщить пользователю о прохождении регистрации и просьбой потвердеть аккаунт перейдя по специально сгенерированной ссылке из письма и далее обработать ссылку сравнивая код и действия подтверждения.
В случае успеха мы активируем и незамедлительно авторизуем пользователя или выводим шаблон о неудаче и дальнейшей инструкцией по разрешению данной ситуации.
Напоследок join_resend_view показывает форму для повторной отправки кода подтверждения и отправляет новое письмо если она корректно заполнена.
Декоратор
Декораторы в python это просто обертки, которые позволяют выполнять код до или после вызываемой функции.
В представлениях мы используем декоратор anonymous_required. Его задача проверить не авторизирован ли пользователь в данный момент, и в случае если вход уже выполнен, то отобразить шаблон ошибки.
В директории accounts создаем файл decorators.py:
from django.shortcuts import render
def anonymous_required(view_func):
def wrapped_view(request, *args, **kwargs):
if request.user.is_anonymous:
return view_func(request, *args, **kwargs)
return render(request, 'accounts/anonymous_required.html')
return wrapped_view
Шаблоны представлений и декоратора мы опишем в соответствующим разделе.
Маршруты
Для начала создаем маршруты внутри приложения. Переходим в accounts и создаем файл urls.py:
from django.conf.urls import url
from . import views
app_name = 'accounts'
urlpatterns = [
url(r'^join/$', views.join_view, name='join'),
url(r'^join/confirm/(?:(?P<code>\w+)/)?$', views.join_confirm_view, name='join_confirm'),
url(r'^join/resend/$', views.join_resend_view, name='join_resend'),
]
Здесь мы просто подключаем ранее созданные представления к маршрутам давая им осмысленные имена. Данные сокращения удобно использовать внутри проекта, например, в шаблонах.
Теперь нам нужно подключить локальные маршруты приложения Аккаунты к глобальному файлу адресов проекта. В каталоге проекта переходим к директории zero и открываем urls.py и приводим к следующему виду:
from django.conf.urls import url, include
from django.contrib import admin
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^accounts/', include('accounts.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
# Django Debug Toolbar
if settings.DEBUG:
import debug_toolbar
urlpatterns += [
url(r'^__debug__/', include(debug_toolbar.urls)),
]