Последние 15 недель мы активно работали над проектом «Стиллион», первым нашим мейнстрим-проектом, написанным на Django. Был приобретен интересный опыт, которым мы хотели бы поделиться с сообществом.
Статья, прежде всего, будет интересна новичкам в Django.
Когда мы делали комментарии, решили, что оптимальным вариантом будет авторизация через сторонние сервисы (вконтакте, фейсбук, openid и иже с ними). Это очень удобно для пользователя, поскольку ему не нужно придумывать и помнить массу паролей от разных ресурсов. Для того, чтобы сделать это быстро и просто, есть сервис Loginza. Интерфейс нам не очень понравился и мы реализовали интеграцию с основными сервисами самостоятельно.
За основу был взят модуль publicauth, но его пришлось основательно допилить. Дело не ограничилось добавлением интеграции с мейл.ру и другими российскими сервисами. Мы добавили «правильную» проверку подписи провайдеров openId и сделали достаточно дружественный виджет в «два клика».
На практике, одной из слабых сторон django оказался ORM. Он, как и все ORM, способствует порождению большого количества запросов и потребляет много памяти, когда извлекает данные. Без применения кеширования генерация главной страницы занимала несколько секунд. Из возможных стратегий оптимизации кеширование оказалось самым дешёвым и эффективным, так как схема БД не позволяла применять штатные средства, такие как select_related.
Резюме: кешируйте с умом:-))
Django — отличный фреймворк с большим количеством неплохих дополнений; когда пользуешься им, понимаешь, что он был создан для нашего удобства. Приятного кодинга!
Статья, прежде всего, будет интересна новичкам в Django.
Модули Django
south
South — механизм миграции схем и данных в БД для django, то, без чего жить невозможно при совместной разработке. К сожалению, в Джанге нет штатного механизма миграций для отслеживания изменений в схеме базы данных проекта. Для восполнения этого пробела мы использовали south, который показал себя с хорошей стороны, главное вникнуть в то как он работает, в документации всё отлично описано. Грабли: миграции можно накатывать без фикстур, этим надо пользоваться. Миграции данных надо писать руками. При использовании нештатных полей (например WYSIWYG-поле) и последующего отказа от них старые миграции не будут работать (но их можно переписать вручную).django-mptt
Реализация nested sets для моделей django. Добавляет соответствующие поля, а также методы работы с деревом. Незаменимая штука для реализации иерархических структур в реляционной СУБД. Для представления деревьев в админке использовали fein-cms.django-annoying
Набор полезных утилит, таких как декораторы видов render_to и ajax_request или HttpResponseReload. Рекомендуем для повышения элегантности кода.django-debug-toolbar
Модуль, отображающий панель с отладочной информацией. Нас прежде всего интересовал лог SQL-запросов, который дополнен информацией об источнике запроса, временем и т.п.pymorphy
Морфологический анализатор, интегрируемый с Django. Используется для склонения слов, которые хранятся в нормальной форме (то есть избавляет нас от хранения различных форм одного слова). Ещё умеет ставить слова во множественное число:morph.pluralize_inflected_ru(u'ПОПУГАЙ', 38)
>>> ПОПУГАЕВ
Недостатки — медленный sqlite в качестве бекенда (есть более быстрые альтернативы Shelve, CDB и Tokyo Cabinet, но нам они не нравятся), не все слова корректно обрабатывает, но это бывает редко.pytils
Чтобы не страдать от «18 март 2011» для работы с русскими датами мы используем pytils. Модуль, кстати, умеет транслитерировать русский текст и выбирать правильный падеж в зависимости от числа, как и pymorphy (правда, без словаря, придётся хранить в шаблоне 3 формы слова).sorl-thumbnail
Приложение для автоматического создания миниатюр изображений. Работает на базе key-value хранилища (в качестве бекэнда использован, разумеется, доступный из коробки redis). В бэкенде хранятся не сами миниатюры (они хранятся в файлах), а всего лишь мета-информация (принципиальная схема работы модуля).{% thumbnail image "100x100" crop="top" as im %}
<img src="{{ im.url }}">
{% endthumbnail %}
django-compress
Склейка и минификация CSS и JS. В конфиге хранятся наборы файлов для склейки, в шаблоне указываем название сборки и compress генерирует минифицированную версию (фильтры YUI и CSSMin). Можно расширять функциональность своими фильтрами. Поддерживает версионное название файлов, что очень удобно при выставлении заголовка Expires на долгое время вперёд (manage.py syncompress при выкладке на продакшен обновит названия и содержимое минифицированных файлов сам).django-sentry
Очень полезное приложение от создателей DISQUS, позволяющее удобно логировать ошибки в базу данных. Sentry перехватывает исключения (например, Http404), сохраняет их и предоставляет красивый интерфейс, в котором показана частота возникновения ошибки (в том числе графически). Возможен сбор ошибок с нескольких серверов. Обзор Sentry на Хабреdjango-admin-tools
Приложение помогает сделать дашборд админки полезным. Имеется встроенный набор виджетов, но не составит труда написать свои. Также можно сформировать меню под свои задачи, которое будет доступно на всех страницах админки. Обзор Admin Tools на ХабреКомментарии
Когда мы делали комментарии, решили, что оптимальным вариантом будет авторизация через сторонние сервисы (вконтакте, фейсбук, openid и иже с ними). Это очень удобно для пользователя, поскольку ему не нужно придумывать и помнить массу паролей от разных ресурсов. Для того, чтобы сделать это быстро и просто, есть сервис Loginza. Интерфейс нам не очень понравился и мы реализовали интеграцию с основными сервисами самостоятельно.
За основу был взят модуль publicauth, но его пришлось основательно допилить. Дело не ограничилось добавлением интеграции с мейл.ру и другими российскими сервисами. Мы добавили «правильную» проверку подписи провайдеров openId и сделали достаточно дружественный виджет в «два клика».
Оптимизация призводительности
На практике, одной из слабых сторон django оказался ORM. Он, как и все ORM, способствует порождению большого количества запросов и потребляет много памяти, когда извлекает данные. Без применения кеширования генерация главной страницы занимала несколько секунд. Из возможных стратегий оптимизации кеширование оказалось самым дешёвым и эффективным, так как схема БД не позволяла применять штатные средства, такие как select_related.
Кэширование
Кеширование блоков по таймауту, доступное «из коробки», нас не устраивало, так как не предусматривало удобного способа сбрасывать кеш. Поэтому была выбрана следющая стратегия: кеш живёт бесконечно долго (TIMEOUT=0), а одной из частей ключа записи в кэше является дата последнего обновления основного объекта. Зависимые объекты обновляют основной с помощью post_save сигналов. Таким образом при изменении объекта имя ключа для кэширования автоматически изменяется, что позволяет видеть на сайте самые актуальные данные. В качестве бэкенда кэша используется Redis с алгоритмом вытестения allkeys-lru (давно не использованные ключи кэша будут удалены при достижении ограничения maxmemory). В редисе, кстати, мы храним ещё и сессии пользователей, чтобы разгрузить бд ещё немного.Order by RAND()
Чтобы не нагружать базу данных выборкой случайных значений через .order_by('?'), используется следующий подход: данные, которые необходимо перемешать, достаются и кладутся в кеш (особенно, если логика выборки этих данных не тривиальна и требует большого числа запросов) в виде списка идентификаторов, а при выдаче к этому списку применяется random.shuffle().Резюме: кешируйте с умом:-))
В качестве заключения
Django — отличный фреймворк с большим количеством неплохих дополнений; когда пользуешься им, понимаешь, что он был создан для нашего удобства. Приятного кодинга!