Накопилось несколько маленьких заметок/советов про python и django, которые на отдельные топики не тянут, поэтому публикую все сразу.
Под катом:
В документации и обучающих примерах по django обычно пишут вьюхи вот так:
Наверное, это правильно — так объяснять, чтобы человек лучше понимал, что происходит. Но в реальной жизни этот код пишется ровно в 2 раза короче:
Фишки:
В статье про админку обещал рассказать про графики, но все никак руки не доходили, нехорошо получилось. Да и рассказывать-то там особо нечего, все слишком просто и «тупо» — графики рисуются через google charts. При этом можно обойтись без всяких библиотек: конструируем себе график по вкусу тут (это полуофициальный инструмент от гугла, на него есть ссылка со справки по api google charts), а потом вставляем полученную строку в шаблон и подставляем переменные вместо тестовых значений.
Есть очень тонкая обертка над google charts: django-chart-tools. Суть — та же: собрать график визуально и заменить переменные, просто с django-chart-tools такие графики удобнее поддерживать.
Выборку данных можно делать просто через django ORM, или, для удобства/скорости, через django-qsstats-magic, в зависимости от задачи.
В итоге (с использованием django-chart-tools и django-qsstats-magic) график пользователей по дням можно вывести примерно так:
потом переменные values и captions передаем в шаблон, а там выводим график таким образом:
Ограничений по количеству обращений у google charts image api нет, там просят только связаться с ними, если > 200тыс обращений в день будет, чтобы они нагрузку распределили. Так что такие графики можно не только в админке использовать.
Используйте для написания тестов django-webtest. Я уже писал про это приложение, но с того времени произошло одно очень важное изменение: django-webtest теперь предоставляет доступ к контексту шаблонов (точно так же, как и стандартный джанговский тест-клиент). Спасибо Gregor Müllegger. Теперь можно писать в таком стиле:
работает также стандартный assertTemplateUsed.
django-webtest лучше любой интеграции с twill, т.к. в них нет доступа к контексту шаблонов и полной поддержки юникода, да и twill не развивается.
django-webtest лучше стандартного тест-клиента, т.к. предоставляет простой API (попробуйте-ка засабмитить форму со значениями по умолчанию через стандартный тест-клиент). Со стандартным тест-клиентом также нельзя протестировать отсутствие csrf-токена (или оченьчер окольными пуями), а с django-webtest это делается тривиально (и даже автоматически). Используйте django-webtest)
Тут бы составить попсовую табличку с фичами: у django-webtest будут везде зеленые галочки, а у twill и стандартного тест-клиента — красные то тут, то там. Даже Ian Bicking считает, что django-webtest — это «Cool!».
Это не просто просто, а очень просто. Отличие от обычных сайтов — только в способе регистрации и входа пользователей. Вместо django-registration ставим и настраиваем django-vkontakte-iframe. Все, теперь все посетители — это зарегистрированные и авторизованные django-пользователи, в остальном можно разрабатывать обычный сайт. Разве что еще позаботиться об js, чтобы подгонять размер iframe под размер страницы.
Кто не знает, pymorphy — это питонья библиотека для работы с русским языком. Умеет морфологический анализ и стрелять из пушки по воробьям: например, склонять слова из базы (или простые словосочетания) прямо в шаблоне django или ставить их в нужную форму в зависимости от числа — без явного перечисления всех вариантов склонения.
pymorphy вырос из статьи на хабре. Признаюсь, код сначала не был хорош, т.к. это был мой первый опыт общения как с python, так и с nlp (обработкой естественных языков). Но морфологический анализатор был-таки написан — и заброшен на год.
В начале этого года возобновил работу над pymorphy и переписал там кучу всего. А весной прошло «соревнование» морфологических анализаторов в рамках конференции Диалог-2010. Там участвовали очень серьезные ребята, результаты проверяли профессиональные лингвисты. pymorphy по дорожке «Морфология» справился лучше всех (скорее всего из-за того, что я как раз тогда выкатил работу с составными словами, записанными через дефис). Также pymorphy был единственным участником, приславшим разбор дорожки с «гразными текстами». Это все особо ни о чем не говорит, но приятно)
1. В setup.py в long_description можно использовать разметку ReST. Удобно положить рядом с setup.py файлик README.rst и потом просто указать
2. Есть сравнительно малоизвестный хак с setup.py. Если разметка выглядит не так, как хотелось, или исправили опечатку, или classifier, то делать новый релиз для исправления этих ошибок нет никакой необходимости: можно просто запустить
Декораторы и оператор with в питоне часто применяются для одного и того же: выполнить какие-то дополнительные действия до или после определенного куска кода. А это означает, что можно написать такую штуку, которую можно использовать одновременно и как декоратор, и как контекст-менеджер для with (например, так: gist.github.com/573536).
Если что, через django-robokassa и django-assist-ru сделаны в продакшне тысячи покупок, > млн рублей.
Пишите еще, кто чем пользуется, добавлю в список.
Чтобы не возиться с геокодированием и кешированием, можно воспользоваться приложением yandex-maps.
Ух, будем считать, что все.
Под катом:
- как упростить код вьюх ровно в 2 раза
- легкий способ рисования графиков
- почему Ian Bicking воскликнул «Cool!»
- приложения для ВКонтакте на django за 5 минут
- хорош ли pymorphy?
- пара фишек насчет выкладки пакетов на pypi
- что общего между декораторами и with-контекст-менеджерами
- принимаем оплату на django-сайтах
- показываем Яндекс.Карту для заданного адреса
Django: упрощаем код вьюх
В документации и обучающих примерах по django обычно пишут вьюхи вот так:
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
# обрабатываем данные. Например, делаем form.save()
# ...
return HttpResponseRedirect('/thanks/') # после POST-запроса делаем редирект
else:
form = ContactForm()
return render_to_response('contact.html', {
'form': form,
}, context_instance=RequestContext(request))
Наверное, это правильно — так объяснять, чтобы человек лучше понимал, что происходит. Но в реальной жизни этот код пишется ровно в 2 раза короче:
def contact(request):
form = ContactForm(request.POST or None)
if form.is_valid():
# обрабатываем данные. Например, делаем form.save()
# ...
return redirect('url_name', param1=value)
return direct_to_template(request, 'contact.html', {'form': form})
Фишки:
- Для unbound-форм is_valid всегда возвращает False. Если после этого сразу непонятно, как работает код
ContactForm(request.POST or None)
, то разберитесь в качестве упражнения, расписывать не буду. Это простая и полезная идиома. - Всегда используйте
django.shortcuts.redirect
для редиректов. Он умеет реверсить названия url'ов, вызывать get_absolute_url или просто перенаправлять по url'у - Используйте
django.views.generic.simple.direct_to_template
вместоrender_to_response
. Они делают почти одно и то же, ноdirect_to_template
использует RequestContext вместо Context, который и так нужен в большинстве случаев. Вместоdirect_to_template
можно использовать декоратор render_to из django-annoying, но это уже дело вкуса, кому как нравится.
Django: рисуем графики
В статье про админку обещал рассказать про графики, но все никак руки не доходили, нехорошо получилось. Да и рассказывать-то там особо нечего, все слишком просто и «тупо» — графики рисуются через google charts. При этом можно обойтись без всяких библиотек: конструируем себе график по вкусу тут (это полуофициальный инструмент от гугла, на него есть ссылка со справки по api google charts), а потом вставляем полученную строку в шаблон и подставляем переменные вместо тестовых значений.
Есть очень тонкая обертка над google charts: django-chart-tools. Суть — та же: собрать график визуально и заменить переменные, просто с django-chart-tools такие графики удобнее поддерживать.
Выборку данных можно делать просто через django ORM, или, для удобства/скорости, через django-qsstats-magic, в зависимости от задачи.
В итоге (с использованием django-chart-tools и django-qsstats-magic) график пользователей по дням можно вывести примерно так:
# исходные данные
qs = User.objects.filter(is_active=True)
end = datetime.today()
start = end-timedelta(days=30)
# готовим данные для графика
data = QuerySetStats(qs, 'date_joined').time_series(start, end)
values = [t[1] for t in data]
captions = [t[0].day for t in data]
потом переменные values и captions передаем в шаблон, а там выводим график таким образом:
{% load chart_tags %}
{% bar_chart values captions «580x100» %}
Ограничений по количеству обращений у google charts image api нет, там просят только связаться с ними, если > 200тыс обращений в день будет, чтобы они нагрузку распределили. Так что такие графики можно не только в админке использовать.
Django: тесты
Используйте для написания тестов django-webtest. Я уже писал про это приложение, но с того времени произошло одно очень важное изменение: django-webtest теперь предоставляет доступ к контексту шаблонов (точно так же, как и стандартный джанговский тест-клиент). Спасибо Gregor Müllegger. Теперь можно писать в таком стиле:
# ...
response = page.forms['my-form-id'].submit().follow()
assert response.context['user'] == self.user
работает также стандартный assertTemplateUsed.
django-webtest лучше любой интеграции с twill, т.к. в них нет доступа к контексту шаблонов и полной поддержки юникода, да и twill не развивается.
django-webtest лучше стандартного тест-клиента, т.к. предоставляет простой API (попробуйте-ка засабмитить форму со значениями по умолчанию через стандартный тест-клиент). Со стандартным тест-клиентом также нельзя протестировать отсутствие csrf-токена (или очень
Тут бы составить попсовую табличку с фичами: у django-webtest будут везде зеленые галочки, а у twill и стандартного тест-клиента — красные то тут, то там. Даже Ian Bicking считает, что django-webtest — это «Cool!».
Django: пишем приложение для Вконтакте
Это не просто просто, а очень просто. Отличие от обычных сайтов — только в способе регистрации и входа пользователей. Вместо django-registration ставим и настраиваем django-vkontakte-iframe. Все, теперь все посетители — это зарегистрированные и авторизованные django-пользователи, в остальном можно разрабатывать обычный сайт. Разве что еще позаботиться об js, чтобы подгонять размер iframe под размер страницы.
Python/Django: работа с русским языком
Кто не знает, pymorphy — это питонья библиотека для работы с русским языком. Умеет морфологический анализ и стрелять из пушки по воробьям: например, склонять слова из базы (или простые словосочетания) прямо в шаблоне django или ставить их в нужную форму в зависимости от числа — без явного перечисления всех вариантов склонения.
pymorphy вырос из статьи на хабре. Признаюсь, код сначала не был хорош, т.к. это был мой первый опыт общения как с python, так и с nlp (обработкой естественных языков). Но морфологический анализатор был-таки написан — и заброшен на год.
В начале этого года возобновил работу над pymorphy и переписал там кучу всего. А весной прошло «соревнование» морфологических анализаторов в рамках конференции Диалог-2010. Там участвовали очень серьезные ребята, результаты проверяли профессиональные лингвисты. pymorphy по дорожке «Морфология» справился лучше всех (скорее всего из-за того, что я как раз тогда выкатил работу с составными словами, записанными через дефис). Также pymorphy был единственным участником, приславшим разбор дорожки с «гразными текстами». Это все особо ни о чем не говорит, но приятно)
Python: пара трюков для выкладки пакетов на pypi
1. В setup.py в long_description можно использовать разметку ReST. Удобно положить рядом с setup.py файлик README.rst и потом просто указать
long_description = open('README.rst').read()
После этого на странице проекта на pypi сразу будет справка по нему — это просто, удобно, и в 90% устраняет необходимость в мороке с отдельной документацией (тут еще такое замечание — если все же кажется, что пакету нужна документация с навигацией и тд, то стоит задуматься — возможно, пакет делает слишком много?).2. Есть сравнительно малоизвестный хак с setup.py. Если разметка выглядит не так, как хотелось, или исправили опечатку, или classifier, то делать новый релиз для исправления этих ошибок нет никакой необходимости: можно просто запустить
./setup.py register
и данные обновятся.Python: декораторы и with
Декораторы и оператор with в питоне часто применяются для одного и того же: выполнить какие-то дополнительные действия до или после определенного куска кода. А это означает, что можно написать такую штуку, которую можно использовать одновременно и как декоратор, и как контекст-менеджер для with (например, так: gist.github.com/573536).
Django: принимаем платежи на сайте
Если что, через django-robokassa и django-assist-ru сделаны в продакшне тысячи покупок, > млн рублей.
Пишите еще, кто чем пользуется, добавлю в список.
Python/Django: показываем Яндекс.карту на сайте
Чтобы не возиться с геокодированием и кешированием, можно воспользоваться приложением yandex-maps.
Ух, будем считать, что все.