Pull to refresh

Сумбурные заметки про python и django

Reading time 5 min
Views 46K
Накопилось несколько маленьких заметок/советов про python и django, которые на отдельные топики не тянут, поэтому публикую все сразу.

Под катом:
  • как упростить код вьюх ровно в 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 это делается тривиально (и даже автоматически). Используйте django-webtest)

Тут бы составить попсовую табличку с фичами: у 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.

Ух, будем считать, что все.
Tags:
Hubs:
+147
Comments 37
Comments Comments 37

Articles