Django

DRY запросы для моделей Django

Представте, что вам нужно создать музыкальную базу. Она должна включать в себя песни, альбомы и исполнителей. Причем одну и туже песню могут исполнять несколько исполнителей. В упрощенном виде мы получаем такую структуру:

from django.db import models


class Artist(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)


class Album(models.Model):
    name = models.CharField(max_length=50)
    release_date = models.DateField()


class Song(models.Model):
    artists = models.ManyToManyField(Artist)
    albums = models.ManyToManyField(Album)
    name = models.CharField(max_length=100)
    release_date = models.DateField()

Вы можете заметить, что получить информацию об исполнителях той или иной песни не просто. Предположим, нам надо получить всех исполнителей в альбоме «Lion King». Для этого вам надо выполнить следующее:

Простые советы по ускорению тестов Django

TDD (Test Driven Development) полезная и удобная практика для написания качественного кода. Согласно ей вы не можете писать код, не написав предварительно тесты для него.

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

В данном посте я перечислю некоторые приемы, которые помогут вам значительно ускорить выполнение тестов Django. На момент написания статьи выполнение набора из 250 тестов занимало около 5 секунд, по сравнению 50 секундами на выполнения тех же тестов, но еще не оптимизированых. Т.е. это в 10 раз быстрее.

Django: модели, инкапсуляция и целостность данных

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

Отсылка почты через SMTP Яндекс.Почты в Django

С 16 сентября Яндекс Почта перешла полностью на протокол SSL для приема и отправки почты. С этого момента отправка почты через порт 25 сервера smtp.yandex.ru стало невозможным. Теперь для работы нужно подключаться к порту 465. И вот тут вылезла проблема. Стандартный SMTP бекэнд, который идет с Django не хочет подключаться. Ни с параметром use_tls, ни без него. Молча висит в ожидании чуда.

Решением стало использование своего SMTP бекэнда, который является копией стандартного с изменением всего одной строки. В строке 47 файла django.core.mail.backends.smtp.EmailBackend нужно заменить smtplib.SMTP на smtplib.SMTP_SSL.

self.connection = smtplib.SMTP_SSL(self.host, self.port,
                                   local_hostname=DNS_NAME.get_fqdn())

После этого все сразу заработало.

Версия Django: 1.6.5

Portfolio: Wok.lv

Wok.lv

WOK.lv - Бесплатная доставка китайской еды в коробочках в Риге.

Technologies: Python, Django, MySql

Тестирование сообщений в Django

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

Архитектура шаблонов Django

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

Urlize Middleware

В ходе работы с SEO потребовалось на сайте Mojalanka выделять линками различные слова и фразы. Перелапачивать каждый раз кучу статей и описаний объектов при добавлении или удалении фразы - неблагодарное занятие. Можно что-то забыть или пропустить. Да и долго это… Следовательно нужно что-то более гибкое. Тут на помощь приходят middleware Django. Они позволяют сделать обработку уже сгенерированной страницы с целью замены определенных фраз на линки. Искомые фразы, а также страницы, на которые они должны указывать, храниться в базе. К ним, конечно имеется админка, но это не тема поста, тут все просто.

Django ORM и Group By

Формирование сложных запросов с использованием Django ORM без написания SQL кода может быть не всегда очевидной вещью. Например, подсчет количества одинаковых записей в базе, отфильтрованных согласно определенному критерию. В SQL это решается просто с использованием GROUP BY и COUNT(). В Django ORM для этого имеются агрегации.

Portfolio: The-K-Market.com

The-K-Market.com - Хранилище образовательных видеоматериалов с возможностью заработка с помощью собственных видео уроков.

Технологии: Python, Django, MySql

Middleware для сохранения referer url

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

Работа со сторонней базой данных в django

Возникла потребность получать информацию из соседнего проекта. В частности авторизовывать пользователей не по собственной базе, а по чужой. Писать отдельный API для этого не хотелось, базы находятся рядом и доступны одному пользователю. Поэтому решено было настроить модели Django поверх уже существующих таблиц. Что нам для этого потребовалось ? А потребовался отдельный роутер для базы данных. Его задача определять на какую базу отправлять запросы для каждого из приложений.

Сложные запросы в Django ORM

Задача сделать выборку списка продуктов из базы данных, цена которых находиться в некотором диапазоне, задаваемом пользователем. Сложность заключается в том, что в базе цены хранятся в различных валютах. Нет, хранить в одной валюте не подходит, т.к. курсы меняются, а пользователи из разных стран… И им удобнее оперировать со своей валютой. Итак. Поскольку кроме этого имеются еще куча фильтров для того же списка, то отказываемся от raw sql. Воспользуемся объектом Q (django.db.models.Q) из Django ORM. from django.db.models import Q

Product.objects.filter(
    Q(currency="EUR") & Q(price__gte=price_min_eur) |
    Q(currency="USD") & Q(price__gte=price_min_usd) |
    Q(currency="EUR") & Q(price__lte=price_max_eur) |
    Q(currency="USD") & Q(price__lte=price_max_usd))

В результате получаем:

SELECT *
FROM products
WHERE (currency="EUR" AND price>=%s) OR
      (currency="USD" AND price>=%s) OR
      (currency="EUR" AND price<=%s) OR
      (currency="USD" AND price<=%s)

Тестирование и South

Если в проекте используется система миграций South, то при тестировании проекта Django каждый раз прогоняет все миграции. Это занимает достаточно времени. Для отключения этого достаточно выставить в settings.py переменные:

SKIP_SOUTH_TESTS = True
SOUTH_TESTS_MIGRATE = False

Первая отключает тесты самого South. Вторая - миграции при прогоне собственных тестов. Т.е. Django будет сразу создавать актуальную структуру базы данных.