Pull to refresh

Прикручиваем django-registration

Reading time 6 min
Views 56K
Нужно было прикрутить регистрацию на сайт. Вспомнил про django-registration (классический django reusable app). Первое, что удивило — в исходниках не было шаблонов. Пришлось немного покопаться в интернете, поискать ответы на вопросы и поделиться результатом.

Вобщем, скачал django-registration, почитал доки и гугл, стал подключать:

# добавляем приложение в setting.py
ACCOUNT_ACTIVATION_DAYS = 2 # кол-во дней для хранения кода активации

# для отправки кода активации
AUTH_USER_EMAIL_UNIQUE = True
EMAIL_HOST = 'localhost'
EMAIL_PORT = 1025
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
EMAIL_USE_TLS = False
DEFAULT_FROM_EMAIL = 'info@google.ru'

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.admin',
    'registration', # это наш reusable app
)

# добаляем урлы в urls.py
urlpatterns = patterns('',
    (r'^accounts/', include('registration.urls')),
    # Uncomment the next line to enable the admin:
    (r'^admin/', include(admin.site.urls)),
)


Стартуем сервер python ./manage.py runserver 8004, открываем http://localhost:8004/accounts/register/ и получае ошибку TemplateDoesNotExist at /accounts/register/ — шаблонов то нет. Значит создаем в templates/registration шаблоны.

# templates/registration/registration_form.html
{% extends "base.html" %}
{% block content %}
<h1>Регистрация</h1>
<form method="post" action="">
<dl class="register">
{% for field in form %}
    <dt>{{ field.label_tag }}</dt>
    <dd class="clearfix">{{ field }}
    {% if field.help_text %}<div class="clearfix">{{ field.help_text }}</div>{% endif %}
    {% if field.errors %}<div class="myerrors clearfix">{{ field.errors }}</div>{% endif %}
    </dd>
{% endfor %}
</dl>
<input type="submit" value="Зарегистрироваться" / class="clearfix">
</form>
{% endblock %}


В итоге получилась форма регистрации. Чтобы название полей звучали по-русски, надо не забыть прописать в setting.py

LANGUAGE_CODE = 'ru-RU'  # для русской локали
USE_I18N = True # интернационалицация по-умолчанию включена


И чтобы завершить регистарацию, надо синхронизировать базу python ./manage.py syncdb (создается таблица registration_registrationprofile). Стоит также отметить, что по умолчанию django-registration не проверяет e-mail нового пользователя на уникальность. Чтобы поправить это, в файле registration/views.py надо поменять:

"""
# функция использует форму RegistrationForm без проверки
# надо заменить на RegistrationFormUniqueEmail
def register(request, success_url=None,
             #form_class=RegistrationForm,
             form_class=RegistrationFormUniqueEmail,
             profile_callback=None,
             template_name='registration/registration_form.html',
             extra_context=None):


Но, как правильно поправил в комментариях lizendir — править код библиотеки — плохо. Лучше в urls.py перед подключением registration.urls добавить свой url () такого вида:
url(r'^register/$', 'registration.views.register', {'form': RegistrationFormUniqueEmail}, name='registration_register'),
url('', include('registration.urls')),


Для минимально-достаточного функционирования необходимо создать в templates/registration/ еще несколько файликов:

# формирование темы письма - текстовый файл в одну строчку
# activation_email_subject.txt
Активация аккаунта – {{ site }}

# текст письма
# activation_email.txt
Регистрация на сайте
Для активации вашего аккаунта необходимо перейти по ссылке:
{{ site }}/accounts/activate/{{ activation_key }}/
Спасибо!

# шаблон окончания регистрации
# registration_complete.html
{% extends "base.html"  %}
{% block content %}
<h1>Регистрация завершена</h1>
Спасибо за уделённое время. На ваш e-mail отправлен
код подтверждения. Необходимо подтвердить регистрацию,
просто кликнув по указанной ссылке.<br/><br/>
{% endblock %}

# страница активации
# activate.html
{% extends "base.html" %}
{% block content %}
<h1>Активация</h1>
Привет, {{ account }}!<br/>
Ваша учетная запись активирована. <a href="{% url auth_login %}">Заходите</a> на сайт.
<br/><br/>
{% endblock %}


Но чтобы регистрация прошла успешно, надо сделать тестовый mail-сервер, куда будет отправлено письмо с текстом и кодом акцивации. Благо, в Python есть быстрое решение — просто набираете в командной строке:

python -m smtpd -n -c DebuggingServer localhost:1025

Оставляем терминал открытым, запускает в дополнительном терминальном окне django-сервер, заходим на http://localhost:8004/accounts/register/ и регистририруемся. В почтовом дебаггере высветится текст письма в quoted-printable кодировке. Но нам достаточно скопировать и вставить строку вида example.com/accounts/activate/b3842d8f0b08a548a0372de9e79b6bd909bf8e6e/ и добавить к нашему localhost:8004. Получается: http://localhost:8004/accounts/activate/b3842d8f0b08a548a0372de9e79b6bd909bf8e6e/. Заходим и активируем аккаунт. Регистрация завершена. Ура!

Для авторизации нам необходимы еще 2 шаблона — login.html и logout.html:

# templates/registration/login.html
{% extends "base.html" %}
{% block content %}
<h1>Авторизация</h1>

{% if user.is_authenticated %}
Что такое, {{ user.username }}? Вы же уже авторизорваны.
Впрочем, всегда можно <a href="{% url auth_logout %}">выйти</a>.<br/><br/>
{% else %}

{% if form.non_field_errors %}
{{ form.non_field_errors }}
{% endif %}

<form method="post" action="">
<dl class="register">  
{% for field in form %}
    <dt>{{ field.label_tag }}</dt>
    <dd class="clearfix">{{ field }}
    {% if field.help_text %}<div class="clearfix">{{ field.help_text }}</div>{% endif %}
    {% if field.errors %}<div class="myerrors clearfix">{{ field.errors }}</div>{% endif %}
    </dd>
{% endfor %}
</dl>
<input type="submit" value="Вход" / class="clearfix">
</form>
   
<script type="text/javascript">
document.getElementById('id_username').focus()
</script>

 <br/><br/>
<ul>
    <li><a href="{% url auth_password_reset %}">Забыли пароль?</a></li>
    <li><a href="{% url registration_register %}">Регистрация</a></li>
</ul>  
{% endif %}
{% endblock %}


# templates/registration/logout.html
{% extends "base.html"  %}
{% block content %}
<h1>Выход</h1>
Спасибо, что были с нами. Ждем вас снова.<br/><br/>
{% endblock %}


Конечно, это не всё — в registration/urls.py есть урлы для отправки забытого пароля и ресета. Но для минимального функционала достаточно. Единственное что — django-админка не показывает по умолчанию, активирован пользователь или нет. Поправим это. Сделаем новое приложение django-admin.py startapp customuseradmin, прописываем его в INSTALLED_APPS после django.contrib.admin и в customuseradmin/admin.py пишем что-то вроде:

# -*- coding:utf-8 -*-
from django.contrib import admin
from django.contrib.auth.models import User, Group
from django.contrib.auth.admin import UserAdmin    

admin.site.unregister(User)

class CustomUserAdmin(UserAdmin):
    list_display = ('username', 'email', 'is_staff','is_active',)
    list_filter = ('is_staff', 'is_superuser', 'is_active',)    
admin.site.register(User, CustomUserAdmin)


Теперь всё. Если где ошибся — поправьте, пожалуйста.
Tags:
Hubs:
+26
Comments 53
Comments Comments 53

Articles