7 августа 2010 г.

musicmans.ru | Как сделать сайт на Django | Пользователи. Личные сообщения. Уведомления

Пока Вы разбираетесь с тестированием в django, попутно приступим к личным сообщениям, без них трудно представить современный веб-сайт.
Перед тем как приступить, установим еще такую вещь на машину разработчика.

#pip install git+git://github.com/robhudson/django-debug-toolbar
Смело ставим последнюю версию, ибо если что-то сломается, то на машине разработчика это не критично.
development.py:

INSTALLED_APPS += (
'django.contrib.admin',#tests
'debug_toolbar',
)

MIDDLEWARE_CLASSES += (
'debug_toolbar.middleware.DebugToolbarMiddleware',
)

INTERNAL_IPS = ('127.0.0.1',)


Обновляем localhost:


Поинтересуйтесь содержимым пунктов меню, там много интересного.

Итак, личные сообщения. Опять все написано за нас. Устанавливаем из транка (кстати, вот консольный svn клиент для windows):

>pip.exe install svn+http://django-messages.googlecode.com/svn/trunk/@141#egg=django_messages

141-я ревизия транка на данный момент, как написано на странице проекта это будущая версия 0.5, совместимая с Django 1.2 (как раз то, что нам нужно). Не забываем requirements.txt (кстати, я подумал, что неплохо было бы сначала добавлять строчку в requirements.txt, а ставить основываясь на файле. Надо только использовать одну директорию с кешом pip, чтобы он постоянно не скачивал дистрибутивы. Ставить установленные приложения по новой он не будет, но мы будем уверены, что не забудем прописать все приложения в requirements.txt и не испытаем проблем на сервере с сайтом).

Документация по настройке. Тут кстати возникает путаница, здесь приложение указано как django_messages, а в документации используется messages, так что используем django_messages.

Изменим темплейты.

Скопируем из приложения и изменим под свои нужды.



В документации к приложению читаем, что оно использует django-mailer и django-notification, если они установлены. Первое у нас есть, ставим второе (хорошее приложение, пригодится в будущем).
>pip.exe install git+git://github.com/jtauber/django-notification@3f023adf0ce2eafcee744904e2c358792f253721@egg=notification

Пропишем 'django_messages', 'notification' в приложения, настроим url.py. Синхронизируем базу.

Просмотрим таблицу notification_noticetype, в ней должны находиться оповещения о работе с личными сообщениями. Приложение notification рассмотрим ниже.

Как только мы видим список чего бы то ни было (список входящих сообщений), сразу рождаются мысли о пагинации. И как не удивительно :-) , django поддерживает ее из коробки, а чтобы было совсем просто установим приложение django-pagination.

>pip.exe install git+git://github.com/ericflo/django-pagination@47e7ec874cd7dddda5ed13ffb6993a64dced2537

Настраиваем. Добавляем css разметку.

А также переведем пару строк, так как в приложении нет русской локализации, djutils\locale\ru_RU\LC_MESSAGES\django.po:
msgid "previous"
msgstr "назад"

msgid "next"
msgstr "вперед"

Не забудем скомпилировать.

в темплейтах с сообщениями добавляем (с месторасположением самостоятельно, 2-ка для теста):

{% load pagination_tags %}
{% autopaginate message_list 2 %}
{% paginate %}


В итоге получается:


Чтобы пользователи не были у нас безликими, давайте организуем им вывод профайлов.
В user/url.conf

url(r'^profile/(?P\d+)/$', users_views.userprofile, name='users_profile'),

(блогспот пытается закрыть тег /userprofile_id самостоятельно, конечно это в коде не требуется)
Вид:

@login_required
@render_to('users/user_profile.html')
def userprofile(request, userprofile_id):

request_user = get_object_or_404(User, id=int(userprofile_id), is_active=True)

return {
'request_user' : request_user,
}

Отмечу, что получать надо user, а не наш UserProfile, который еще может быть не создан.

Соответственно, напишем темплейт.



django_messages\templates\notification\ переведите вручную, перевод, который идет с приложением не работает (устарел наверное). Скопируем темплейты в users/templates, создадим папку locale в приложении и запустим создание файла перевода:
>python C:\Python26\Lib\site-packages\django\bin\django-admin.py makemessages -e .html,.txt --locale=ru_RU
в директории users.
После редактирования скомпилируем.

Темлейт для уведомлений notices.html для самостоятельного написания (можно подсмотреть в pinax).

Что такое notification? Это приложение для уведомлений. Когда происходит событие в системе, мы имеем возможность создать уведомление для пользователя, с возможностью настройки дополнительных рассылок уведомлений:

* при логине на сайт.
* по почте (настраивается пользователем).
* по rss

Подключим контекстный процессор "notification.context_processors.notification".

Мне не понравилась часть приложения по работе с url. Поэтому скопировал приложение себе в проект и поправил под свои нужды, получилось примерно следующее:



Пишите сообщения. :)

3 августа 2010 г.

musicmans.ru | Как сделать сайт на Django | Пользователи. Дополнительная аутентификация

В прошлый раз мы остановились на том, что начали создавать приложение users. Давайте создадим openid аутентификацию на сайте.
Я обещал писать бекенды для django-registration, но оказалось существует замечательное приложение для всевозможных видов аутентификации с последующим созданием пользователя и авторизации.

* OpenID - yandex.ru, rambler.ru, yahoo.ru, google.com
* OAuth - twitter.com
* OpenAPI - Вконтакте.ру
* FacebookConnect - facebook.com

Устанавливаем:
c:\Python26\Scripts\pip.exe install hg+http://bitbucket.org/offline/django-p
ublicauth@7371e8f71be1#egg=django-publicauth

Прописываем в requirements.txt.
Добавляем 'publicauth' в INSTALLED_APPS. Добавляем 'annoying.middlewares.RedirectMiddleware' в MIDDLEWARE_CLASSES.

Добавим 'publicauth.PublicBackend' в AUTHENTICATION_BACKENDS.

Запускаем syncdb.

OpenID

Необходимо установить python-openid (2.2.5).

Добавим
(r'', include('publicauth.urls')),
в файл /users/urls.py , тем самым переопределив url login и logout приложения нашими url'ами, и оставив остальные, необходимые для работы приложения. Ознакомимся с содержимым темплейта login.html, и добавим следующую форму в наш login.html:


Openid URL




Создадим директорию publicauth в users/templates/ , скопируем туда содержимое и поправим под наш сайт.
Также в файле users/forms.py создадим форму ExtraForm (форма для заполнения дополнительных полей после сторонней аутентификации, например имя пользователя).
Подсмотреть можно здесь.

PUBLICAUTH_EXTRA_FORM = "users.forms.ExtraForm"

Пробуем логиниться.

Приложение требует установленного и настроенного messages framework, как указано в документации (для самостоятельного рассмотрения) для вывода сообщений. У меня уже оно почти настроено (сообщение при сохранении профиля реализованно как раз через него).

Сообщения к сожалению не переведены, придется сделать это самим.

Создадим файл src/djutils/locale/ru_RU/LC_MESSAGES/django.po и переведем файл.

msgid "To complete registration, check your email and activate your account"
msgstr "Для завершения регистрации проверьте e-mail и активируйте учетную запись"

msgid "We are sorry, but registration is disabled. Come back later"
msgstr "Извините, но регистрация закрыта"

msgid "Please fill openid url field"
msgstr "Пожалуйста, заполните поле openid"

msgid "Your authentication provider returned bad response, please try again"
msgstr "Ваш провайдер аутентификации вернул влохой ответ, попробуйте еще раз"

msgid "You have cancelled OpenID authentication"
msgstr "Вы отменили аутентификацию по OpenID"

msgid "OpenID authentication failed. Reason: %s"
msgstr "Аутентификация OpenID провалилась. Причина: %s"

msgid "You have successfully logged out"
msgstr "Вы успешно вышли"

msgid "Your existing account was merged with new authentication account"
msgstr "Существующая учетная запись была объединена с новой учетной записью"

msgid "Your account is not activated. Please activate it first."
msgstr "Ваша учетная запись не активирована. Пожалуйста, активируйте ее сначала."

msgid "You have successfully authenticated"
msgstr "Вы успешно аутентифицированны"

msgid "Invalid response received from facebook server, please start the authentication process again"
msgstr "Неверный ответ от сервера facebook, пожалуйста запустите процесс аутентификации еще раз"

msgid "Invalid response received from OpenID server, please start the authentication process again"
msgstr "Неверный ответ от сервера OpenID, пожалуйста запустите процесс аутентификации еще раз"

msgid "Invalid response received from vkontakte server, please start the authentication process again"
msgstr "Неверный ответ от сервера vkontakte, пожалуйста запустите процесс аутентификации еще раз"

Скомпилируем (запуск в директории src\apps\djutils\)
>python C:\Python26\Lib\site-packages\django\bin\django-admin.py compilemessages.

Добавим 'django.middleware.locale.LocaleMiddleware', в MIDDLEWARE_CLASSES.

ВКонтакте

Делаем все как по ссылке на хабр. Единственно, я не понял для чего нужно VKONTAKTE_API_KEY, работает и без него, да и в бекенде vkontakte.py он не используется.

Facebook

Делаем по мануалу, ссылка на документацию на facebook.

В настройки надо добавить
FACEBOOK_PROFILE_MAPPING={ 'name': 'username', }

OAuth (Twitter)

Install python-oauth:
>pip.exe install oauth

Настройки:

TWITTER_CONSUMER_KEY = "key"
TWITTER_CONSUMER_SECRET = "secret"
TWITTER_REQUEST_TOKEN_URL = "https://twitter.com/oauth/request_token"
TWITTER_ACCESS_TOKEN_URL = "https://twitter.com/oauth/access_token"
TWITTER_AUTHORIZE_URL = "https://twitter.com/oauth/authorize"
TWITTER_API_URL = "http://twitter.com/users/show.json?user_id=%s"
TWITTER_PROFILE_MAPPING = { 'screen_name': 'username', }

Темплейт:




В итоге, в url auth_login мы должны иметь авторизацию на сайте или аутентификацию в сторонних сайтах в случае неавторизированного пользователя, а также аутентификацию в сторонних сайтах и сопоставления этих профилей с текущим профилем. И, естественно, логин любым из методов для существующего пользователя.

Как обычно, запускаем тесты, мержим транк, делаем развертывание, и сравниваем musicmans.ru.



ps. По поводу тестов. Да все уже написано:
http://djangotesting.com/
http://habrahabr.ru/blogs/django/91471/
http://pyobject.ru/blog/2009/09/13/django-external-test-tools/
http://night-fairy-tales.com/2009/10/django-eclipse.html

Разбираемся, пишем (На данный момент нами написано лишь редактирование профиля в приложении users, вот для него и можно написать тесты).

pps. Насткнулся на баг в тестах django-registration.
Вот решение (developmet.py)

TEST = False
manage_command = filter(lambda x: x.find('manage.py') != -1, sys.argv)
if len(manage_command) != 0:
command = sys.argv.index(manage_command[0]) + 1
if command < len(sys.argv):
TEST = sys.argv[command] == "test"

if TEST:
LANGUAGE_CODE = 'en-us'