Тотальный пример использования django-registration и расширения модели User
В интернете есть много разрозненной информации о django-registration и о расширении стандартной модели Users. Однако, тотального примера, которое позволило бы новичку вникнуть как реализовать задуманную им логику регистрации нет. Я попробовал восполнить этот пробел.
Поставим себе следующие техническое задание:
Для начала создадим новое приложение profile:
Заходим в созданную папку profile, и открываем для редактирования файл models.py. В нашем примере, мы расширим модель пользователя полем проффесия, при чем посетитель сайта при регистрации будет выбирать проффесию из списка. Для удобного редактирования этого списка, мы вынесем его в отдельную модель Work. И так, models.py у нас обрастет таким кодом:
Мы подключаем поле AutoOneToOneField. Создадим в каталоге profile файл fields.py с таким кодом:
Осталось добавить приложение в INSTALLED_APPS (файл настроек settings.py), а также указать директиву AUTH_PROFILE_MODULE:
Этот этап пройден, выполняем python manage.py syncdb и смотрим как создаются новые таблицы.
Для установки django-registration достаточно просто скачать её отсюда, разархивировать архив и положить папку registration в корневую папку вашего проекта. Однако, так поступать категорически не рекомендуется, лучше воспользоватся утилитами установки easy-install либо pip. Но тут есть один нюанс, если просто выполнить:
установится версия 0.7, которая не поддерживает очень удобный механизм — сигналы. Поэтому, чтобы посредством easy-install установить последнюю версию 0.8, необходимо выполнить:
(Возможно, когда вы будете читать эту статью, эта версия не будет последней актуальной, так что не забудьте проверить)
После этого следует добавить в INSTALLED_APPS — 'registration', а также обязательную директиву ACCOUNT_ACTIVATION_DAYS — которая устанавливает в течении скольки дней пользователь может активировать свою запись:
Далее необходимо сделать привязку URL, для этого редактируем файл urls.py, добавляя в urlpatterns строчку:
Теперь для работы осталось только создать шаблоны для регистрации, активации и т.д. Это опять же подробно описано здесь, не будем повторятся.
После этого обновляем базу данных (python manage.py syncdb) и можно тестировать регистрацию. Не забудьте запустить почтовый сервер.
Теперь мы подошли к самому интерестному — добавим поля профиля в регистрационную форму, и несколько кастомизируем регистрацию.
Унасследуем стандартную форму модуля django-registration и добавим в неё наши поля. Создаем forms.py в папке profile:
Обратите внимание как заполняется список выбора. При такой реализации при добавлении в таблицу Work новых строк прийдется перезагружать джангу, но зато список кешируется, и не будет происходить выполнения запроса к базе данных каждый раз при выводе формы. Такой вариант подходит когда таблицу не планируется часто изменять.
Теперь нам надо чтобы бэкэнд django-registration использовал нашу форму вместо своей по умолчанию, для этого в urls.py перед
url(r'^accounts/', include('registration.backends.default.urls')),
добавим
И имортируем форму:
Раньше приходилось переписывать у формы метод save(), в django-registration 0.8 появилась возможность повесить сигнал на создание юзера. Также сразу повесим сигнал на активацию юзера, для того чтобы сразу провести авторизацию.
Создадим signals.py в папке profile:
Теперь осталась импортировать эти функции в urls.py:
Остался последний штрих — мы хотим чтобы после регистрации пользователь попадал на определенную целевую страницу, для этого можно просто повесить представление на url accounts/activate/complete/:
Техническое задание выполнено!
Поставим себе следующие техническое задание:
- Во время регистрации пользователь заполняет дополнительные поля.
- При отправке формы — вся информация сохраняется в профайле, и на почту высылается письмо с ссылкой для активации.
- При переходе по ссылке пользователь активирует свою учетную запись, автоматически авторизуется на сайте, и перенаправляется на определенную страницу.
Расширение модели User
Расширять модель пользователя мы будем соединением нашей модели Profile с стандартной моделью User посредством поля AutoOneToOneField. Подробнее об этом здесь.Для начала создадим новое приложение profile:
django-admin.py startapp profile
Заходим в созданную папку profile, и открываем для редактирования файл models.py. В нашем примере, мы расширим модель пользователя полем проффесия, при чем посетитель сайта при регистрации будет выбирать проффесию из списка. Для удобного редактирования этого списка, мы вынесем его в отдельную модель Work. И так, models.py у нас обрастет таким кодом:
#profile/models.py
# -*- coding: utf-8 -*-
from django.db import models
from django.contrib.auth.models import User
from habr.profile.fields import AutoOneToOneField
class Work(models.Model):
work = models.CharField(max_length = 100, verbose_name = 'Работа')
class Profile(models.Model):
user = AutoOneToOneField(User, related_name='profile', verbose_name=('User'), primary_key=True)
work = models.ForeignKey(Work, verbose_name = 'Вид деятельности')
Мы подключаем поле AutoOneToOneField. Создадим в каталоге profile файл fields.py с таким кодом:
#profile/fields.py
# -*- coding: utf-8 -*-
from django.db.models import OneToOneField
from django.db.models.fields.related import SingleRelatedObjectDescriptor
class AutoSingleRelatedObjectDescriptor(SingleRelatedObjectDescriptor):
def __get__(self, instance, instance_type=None):
try:
return super(AutoSingleRelatedObjectDescriptor, self).__get__(instance, instance_type)
except self.related.model.DoesNotExist:
obj = self.related.model(**{self.related.field.name: instance})
obj.save()
return obj
class AutoOneToOneField(OneToOneField):
def contribute_to_related_class(self, cls, related):
setattr(cls, related.get_accessor_name(), AutoSingleRelatedObjectDescriptor(related))
Осталось добавить приложение в INSTALLED_APPS (файл настроек settings.py), а также указать директиву AUTH_PROFILE_MODULE:
#settings.py
INSTALLED_APPS = (
##
'habr.profile',
##
)
AUTH_PROFILE_MODULE = 'habr.profile.profile'
Этот этап пройден, выполняем python manage.py syncdb и смотрим как создаются новые таблицы.
Прикручиваем и кастомизируем django-registration
Django-registration — это модуль который позволяет легко реализовать на сайте регистрацию с авторизацией по электронной почте (либо без онной). Достаточно подробно о её установке написано здесь, мы же пробежимся по основным нюансам, и займемся кастомизацией.Для установки django-registration достаточно просто скачать её отсюда, разархивировать архив и положить папку registration в корневую папку вашего проекта. Однако, так поступать категорически не рекомендуется, лучше воспользоватся утилитами установки easy-install либо pip. Но тут есть один нюанс, если просто выполнить:
easy_install -Z django-registration
установится версия 0.7, которая не поддерживает очень удобный механизм — сигналы. Поэтому, чтобы посредством easy-install установить последнюю версию 0.8, необходимо выполнить:
easy_install-2.6 <a href="http://cdn.bitbucket.org/ubernostrum/django-registration/downloads/django-registration-0.8-alpha-1.tar.gz">cdn.bitbucket.org/ubernostrum/django-registration/downloads/django-registration-0.8-alpha-1.tar.gz</a>
(Возможно, когда вы будете читать эту статью, эта версия не будет последней актуальной, так что не забудьте проверить)
После этого следует добавить в INSTALLED_APPS — 'registration', а также обязательную директиву ACCOUNT_ACTIVATION_DAYS — которая устанавливает в течении скольки дней пользователь может активировать свою запись:
#settings.py
INSTALLED_APPS = (
##
'habr.profile',
'registration',
##
)
AUTH_PROFILE_MODULE = 'habr.profile.profile'
Далее необходимо сделать привязку URL, для этого редактируем файл urls.py, добавляя в urlpatterns строчку:
url(r'^accounts/', include('registration.backends.default.urls')),
Теперь для работы осталось только создать шаблоны для регистрации, активации и т.д. Это опять же подробно описано здесь, не будем повторятся.
После этого обновляем базу данных (python manage.py syncdb) и можно тестировать регистрацию. Не забудьте запустить почтовый сервер.
Теперь мы подошли к самому интерестному — добавим поля профиля в регистрационную форму, и несколько кастомизируем регистрацию.
Унасследуем стандартную форму модуля django-registration и добавим в неё наши поля. Создаем forms.py в папке profile:
#profile/forms.py
# -*- coding: utf-8 -*-
from django import forms
from registration.forms import RegistrationFormUniqueEmail
from habr.profile.models import Work
WORK_CHOICES = [
(work.id, work.work) for work in Work.objects.all()
]
class RegistrationFormProfile(RegistrationFormUniqueEmail):
work = forms.ChoiceField(choices=WORK_CHOICES, label = 'Работа')
Обратите внимание как заполняется список выбора. При такой реализации при добавлении в таблицу Work новых строк прийдется перезагружать джангу, но зато список кешируется, и не будет происходить выполнения запроса к базе данных каждый раз при выводе формы. Такой вариант подходит когда таблицу не планируется часто изменять.
Теперь нам надо чтобы бэкэнд django-registration использовал нашу форму вместо своей по умолчанию, для этого в urls.py перед
url(r'^accounts/', include('registration.backends.default.urls')),
добавим
url(r'^accounts/register/$', 'registration.views.register', {'backend': 'registration.backends.default.DefaultBackend', 'form_class':RegistrationFormProfile,},
name='registration_register'),
И имортируем форму:
from habr.profile.forms import RegistrationFormProfile
Раньше приходилось переписывать у формы метод save(), в django-registration 0.8 появилась возможность повесить сигнал на создание юзера. Также сразу повесим сигнал на активацию юзера, для того чтобы сразу провести авторизацию.
Создадим signals.py в папке profile:
#profile/signals.py
# -*- coding: utf-8 -*-
from registration.signals import user_registered, user_activated
from habr.profile.models import Profile
from forms import RegistrationFormProfile
from django.contrib import auth
def user_created(sender, user, request, **kwargs):
form = RegistrationFormProfile(request.POST)
profile = Profile(user=user, work_id = int(form.data['work']))
profile.save()
def login_on_activation(sender, user, request, **kwargs):
user.backend='django.contrib.auth.backends.ModelBackend'
auth.login(request,user)
user_activated.connect(login_on_activation)
user_registered.connect(user_created)
Теперь осталась импортировать эти функции в urls.py:
from habr.profile.signals import *
Остался последний штрих — мы хотим чтобы после регистрации пользователь попадал на определенную целевую страницу, для этого можно просто повесить представление на url accounts/activate/complete/:
url(r'^accounts/activate/complete/$', 'gamb.profile.views.redirect_after_activation'),
Техническое задание выполнено!
0 комментариев