Django Framework

индекс
177,76

Ещё 10 батареек для джанго


Продолжаем делиться своим опытом использования полезных батареек для Django.
Первая часть
Ещё рекомендуем «Сумбурные заметки про python и django» и «Django проект PR Hero: что внутри и полученный опыт».

Для Django написано огромное количество пакетов. Из них мы выбрали 10, которые использовали сами в своих последних проектах и которыми остались довольны. Все они есть на PyPI. Они продокументированы и покрыты тестами, где-то больше, где-то меньше. Исключение составляет django-sphinx, о котором отдельно.



django-hvad


Интересная реализация хранения мультиязычных полей в моделях. Для каждой переводимой модели создаётся дополнительная таблица, в которой хранятся исключительно переводные атрибуты.

Пример описания модели:

class DjangoModel(TranslatableModel):
    name = models.CharField(max_length=255, unique=True)
    author = models.CharField(max_length=255)

    translations = TranslatedFields(
        description = models.TextField(),
        description_author = models.CharField(max_length=255),
    )

    def __unicode__(self):
        return self.name


Пример запроса:

DjangoModel.objects.language('en').filter(description_author='Jonas Obrist')


Приложение одно из лучших в своей категории, хоть и альфа. Местами сыровато, что открыто признаёт сам автор. Оно старается минимизировать количество запросов к БД, дружественна к south-миграциям.
Кроме того, django-hvad умеет рисовать симпатичную админку для переводов полей:


Гитхаб
Документация

django-whatever (django-any)


Модуль позволяет отказаться от создания громоздких фикстур для тестов, заменив их простым созданием объектов моделей на лету, заполняя поля случайными данными. Благодаря этому тесты становятся более читабельными и поддерживаемыми.

Вот пример, в котором мы создаём два экземпляра моделей, но указываем при создании лишь те значения полей, которые важны для теста (остальное сделает django-any):

from django_any import any_model

class TestMyShop(TestCase):
    def test_order_updates_user_account(self):
        account = any_model(Account, amount=25, user__is_active=True)
        order = any_model(Order, user=account.user, amount=10)
        order.proceed()

        account = Account.objects.get(pk=account.pk)
        self.assertEquals(15, account.amount)


django-any написал хабраюзер kmmbvnr, а django-whatever это дружественный форк нашего авторства, в котором мы добавили несколько фич и поправили несколько багов.

Github
Доки

django-jenkins


Удобная интеграция Django и Jenkins для упрощения решения задач continious integration от kmmbvnr. Всё очень просто: настраиваешь и пользуешься, никаких нареканий нет.

Хорошие статьи про тестирование в Django и непосредственно про интеграцию с django-jenkins:

Гитхаб
Видео-туториал от автора: “Как начать тестировать и получать от этого удовольствие”

django-guardian


Приложение реализует недостающую из коробки фичу прав на объект, а не на всю модель (object-level permissions). Начиная с Django 1.2 бэкенд аутентификации поддерживает проверку прав на объект, но это не реализовано в самом Django. django-guardian успешно заполняет этот пробел.

Единственным обнаруженным недостатком является, пожалуй, то, что наличие глобальных прав на модель не даёт прав на конкретный объект и требует отдельной проверки.

Гитхаб
Доки

django-email-confirmation


Среди множества других аналогичных батареек, django-email-confirmation не берёт на себя всё и сразу, но то, что берёт — делает хорошо. Позволяет пользователю регистрировать на себя несколько email-адресов, из них выделить основной, подтверждать адреса по почте и управлять всем этим нехитрым процессом. Можно определить собственные шаблоны для писем, можно подружить метод отправки письма с Celery, всё как положено. Является частью проекта Pinax.

Гитхаб

django-compressor / webassets


Два самых интересных, на наш взгляд, приложения для склейки и минификации CSS/JS. В отличие от упоминавшегося в прошлом посте django-compress, не требуют конфига и могут работать с помощью темплейт-тегов, что довольно удобно для верстальщиков. webassets, что примечательно, работает не только с Django (flask-assets). Оба модуля поддерживают Jinja через свои расширения. Любители SAS, LESS, CoffeeScript не уйдут обиженными, препроцессоры тоже поддерживаются.

Мы используем django-compressor и предостерегаем вас от поспешных обновлений на свежие версии приложения на боевых серверах: модуль активно разрабатывается и периодически всплывают неожиданные регрессии (несмотря на тесты). В остальном очень хороший пакет от одного из django core devs.

django-compressor гитхаб
django-compressor доки

webassets гитхаб
webassets доки

django-taggit


Простая батарейка, как по структуре, так и по возможностям. Как ясно из названия, django-taggit реализовывает поддержку тегов. Делает он это на уровне модели с помощью специального менеджера. Неплохо кастомизируется и расширяется через through-модель, сам умеет создавать уже набившее всем оскомину облако тегов и делает некоторые другие стандартные вещи (типа добавить/удалить тег). Документация совсем небольшая, но исчерпывающая, поэтому на знакомство не уйдёт много времени.

Гитхаб
Доки

django-sphinx


Sphinx, популярный поисковый движок, — наше всё, благодаря его скорости, гибкости и способности учитывать особенности русской морфологии, чего не скажешь о его ближайших конкурентах. Несмотря на популярность, существует одно единственное решение-интегратор для Django — django-sphinx.

Что даёт?
  • полная поддержка Sphinx API <= 0.9.9
  • поисковые запросы через менеджер моделей, можно уточнять такие параметры как вес полей или названия индексов прямо в описании класса модели
  • на основе указанных параметров умеет автоматически генерировать sphinx-конфиг
  • псевдо`queryset (SphinxQueryset) на выходе, что также удобно для работы с выборкой
И в то же время:
  • есть проблемы при дополнительной обработке объекта выборки
  • несколько досадных открытых багов в оригинальном пакете django-sphinx (например, exception при использовании метода exclude), хотя они исправлены в нашем форке
  • совсем нет тестов, скудная документация
  • пакет не поддерживается и больше не развивается своим автором
В ближайшие дни мы поделимся с вами опытом работы с этим модулем и постараемся детально описать обнаруженные подводные камни. Масса нюансов тянет на отдельную статью.

Гитхаб (наш форк)

Полезные статьи (местами не совсем актуальные):

django-celery


По-настоящему незаменимая батарейка на более-менее крупных проектах, где без асинхронных задач не обойтись. Фактически, Celery — де-факто стандарт для реализации очередей в питоне, она обладает широким набором фич, поддерживает разнообразные бэкенды и имеет приятный API.

На Хабре была пара хороших статей о том как работать с celery, в том числе настройка и подводные камни при интеграции с Django:
Гитхаб
Документация

django-hosts


Модуль для управления роутингом урлов в зависимости от поддомена, у каждого из которых может быть свой собственный URLConf. Если ваш сайт имеет множество поддоменов, эта батарейка вам пригодится.

Гитхаб
Документация

P.S. Наш скромный вклад в опенсорс github.com/futurecolors/ и github.com/coagulant
+52
13 января 2012, 16:20
233

комментарии (42)

0
tipugin #
Спасибо, интересно! Я так понял, django-whatever — это что-то вроде FactoryGirl для джанго?
0
Prophet #
Судя по описанию, да, только factory_girl более навороченная.
–3
phasma #
Лучше бы Inline формы в админке без модели сделали бы и с возможностью не валидировать эти формы полностью.
0
shaeng #
а для чего это вам?
+1
phasma #
Есть люди, которые заказали CMS у одной конторы. Контора все сделала, но админка там очень неудобная. Потом я начала переделывать все это, добавляя функции вроде гугль календаря, очистки кэшей через админку итд.

Через инлайны сделаны табы для материалов, в одном из инлайнов прикручена загрузка изображений. Для html5 dnd аплоада картинок нужно отключить там валидацию input'ов. Как отключить валидацию целой модели я не нашел, просто сделал вывод пустой формы, которая не позволяет изменять загруженные ранее объекты.

Сейчас вся админка состоит из костылей. Часть кода в этой CMS, которая идет отдельным пакетом, часть кода в самом джанго приложении. Плюс куча наследованных класов с переопределением методов. Я уже подумываю переписать админку с использованием Pyramid, а затем и морду перенести на Pyramid.
+2
artifex #
Проблема же не в Django, а в руках, должны понимать. Зачем отключать валидацию и что эта валидация у вас валидирует мне тоже не до конца понятно. Если форма это ModelForm, то валидацию можно определить/переопределить соответствующими методами.
0
phasma #
class AAdmin(ModelAdmin):

fieldsets = (
(None, {
'fields': ('title', 'img', 'author', 'description', 'recommended')
}),
)
list_display = ('title',)
inlines = [PhotoInline]
tabs = True

def save_model(self, request, obj, form, change):
#Здесь сохрание

def get_urls(self):

from django.conf.urls.defaults import patterns, url
from django.utils.functional import update_wrapper

def wrap(view):
def wrapper(*args, **kwargs):
return self.admin_site.admin_view(view)(*args, **kwargs)
return update_wrapper(wrapper, view)

info = self.model._meta.app_label, self.model._meta.module_name

urlpatterns = patterns('',
url(r'^(.+)/save_sort/$',
wrap(self.save_sort),
name='%s_%s_save_sort' % info),
)
return urlpatterns + super(AAdmin, self).get_urls()

@csrf_exempt
def save_sort(self, request, object_id, extra_context=None):
def __POST(request):
#Парсинг json и запись в БД

if request.POST:
__POST(request)

response = HttpResponse(«OK»)
response.status_code = 200
return response

class PhotoInline(StackedInline):

model = Photo
ordering = ('order',)
template = 'admin/stacked.html'

Получаем редактирование материала и отдельный таб с загрузкой изображений. В шаблоне stacked.html идет вывод формы для загрузки изображений. Нужно отключить вывод формы, т.к. она не нужна, все делается через допметоды save_sort etc через передачу JSON. Если убрать форму, то валидация не проходит. Буду рад, если покажете как отключить валидацию PhotoInline.
+2
frol #
Python без отступов — крууто :)

PS Пользуйтесь тегом <source> и предпросмотром.
+1
phasma #
pastebin.com/b9q6c03c

Жду конструктивных предложений, а не обсуждения рук.
+4
dzenmoon #
Нее, я не удержался от обсуждения рук:
А вы уверены, что можете назвать их прямыми после того, как метод модели отвечает за валидацию данных и возвращает HTTPResponse?

По конструктиву — гугл подсказал ответ: softwaremaniacs.org/forum/django/33642/
0
shaeng #
всё равно не понятно зачем отключать валидацию, ложные срабатывания?
0
Progrik #
Что за контора и что за CMS на Django?
+4
LanG #
Дак сделайте же!
+3
dadon #
Противные джанго-программисты, не хотят за вас писать код :)
0
H1D #
Отлично, спасибо за новую пачку батареек, парочку новых нашел.

Может кто подскажет ищу батарейку для решения такой задачи:
Многие из написанных мною приложений имеют собственные настройки, которые должны быть изменяемы из админки. Пример из головы (не самый удачный) — есть приложение отвечающее за аватары, есть ограничение на размер аватара. Хочется дать клиенту возможность управлять этим ограничением из админки. Идеально привязать настройки прямо к модели, чтобы была иконка «настройки» рядом с иконками «добавить» и «изменить». В тоже время чтобы в коде доступ к настройкам был прозрачный. Например такого рода: settings.app_name.model_name.setting

Пробовал всякие django-appsettings, django-dbsettings и другие но они тупые до невозможности неюзабельны. Где-то интеграция в админку скудная, где-то нет задания дефолтных значений вне БД, отчего нельзя читать настройки при инициализации других приложений.

Если нет такого приложения то я уж готов сам сесть писать…
+1
artifex #
Вот коллега рекоммендует django-livesettings, возможно вам подойдёт.

С другой стороны, почему бы не добавить соответствующий миксин к модели, в котором будут храниться изменяемые значения и которые можно свободно редактировать из админки? Можно также написать какие-нибудь методы, чтобы удобно работать с этими значениями.
0
H1D #
спасибо, гляну приложение

С миксином не понял. Как он поможет в данной ситуации. Поля из миксина окажутся в каждом объекте мдели, а нужно чтоб эти поля были едины для всех моделей. Ну и опять же, пока нет базы, нам не прочитать такие значения (хотя помощи сеттеров/геттеров можно чудеса творить).
0
race1 #
Используем django-compressor, но смущает такой момент — почти каждая страница имеет уникальный набор css/js (пихать всё в одну кучу выйдет очень большой итоговый css и js), что приводит к тому что почти на каждую страницу есть уникальный же склеенный и сжатый файл, что для пользователя проявляется следующим образом — когда открывается новая страница скачивается новый минифицированный css/js, и пока он не скачается страница будет и без стилей и без js. И так для почти для каждой страницы.

Сталкивались ли вы с этим? Как одно из решений проблемы я вижу делать пару минифицированныйх файлов — в одном будут общие для всего сайта css/js, в другом — только уникальные для страницы. Но django-compressor вроде так не умеет.
+1
Progrik #
Ужас какой.
Сколько ж у вас весит несжатый css, если в него со всех страниц стили добавить?
0
race1 #
250 кб :) На самых тяжёлых страницах js ещё в полтора-два раза больше. В сумме после gzip будет 100-300 кб.
+3
frol #
Этот «очень большой» итоговый css и js пользователь скачает ровно один раз и закеширует, так что я не вижу в этом проблемы.

PS Давно 250 кб стало «очень много» для единоразовой загрузки?
0
race1 #
250 kb css плюс, посчитал, около 600 kb js. При этом основной размер дают большие библиотеки на js которые используются всего на паре страниц. По-моему 850 кб css/js это перебор, ещё ведь есть картинки и сама страница. Кроме размера файлов, это же всё нужно выполнить браузеру.

Может я придираюсь и экономлю на спичках, но мне кажется чем меньше страница тем лучше, а некоторым страницам у нас нужна всего пара килобайт css/js, зачем же пол мегабайта тащить? Особенно это чувствительно для landing pages, когда страница с одним абзацем и одной кнопкой будет весть пол мегабайта… не правильно это :)
0
Progrik #
Ну так не делайте таких страниц, вот и всё :)
0
race1 #
Извините, не делать страниц в пару килобайт потому что есть страницы в пол-мегабайта? :) Или не делать страниц в пол мегабайта? Но тут к сожалению никак, используемые библиотеки и минифицированы с склеены и gzip но занимают много.
0
frol #
«При этом основной размер дают большие библиотеки на js которые используются всего на паре страниц.»

Так сделайте один общий набор, характерный для большинства страниц, а на этих нескольких уникальных страницах дополнительно подгружайте эти большие библиотеки (необязательно же всё запихнуть в 1 js файл)
0
race1 #
Да, тоже вариант. Если не получится делать два сжатых файла средствами django-compressor, можно так и поступить. Спасибо.
+1
Prophet #
Можно сделать несколько минифицированных файлов, django-compressor это позволяет. Вообще, это самое правильное решение, когда есть универсальная сборка, общаяя для всех страниц + уникальные минисборки для отдельных.
0
race1 #
Подскажите как, не нашёл этого в доках.
+2
Prophet #
Можно просто несколько тегов создать и всё:
{% compress css %}
    <link rel="stylesheet" href="{{STATIC_URL}}/layout.css" type="text/css">
    <link rel="stylesheet" href="{{STATIC_URL}}/main.css" type="text/css">
{% endcompress %}

{% compress css %}
    <link rel="stylesheet" href="{{STATIC_URL}}/pag1e.css" type="text/css">
    <link rel="stylesheet" href="{{STATIC_URL}}/page1_etc.css" type="text/css">
{% endcompress %}
0
race1 #
Так просто и очевидно, спасибо!
0
zw0rk #
Мне для ассетов очень понравился django-pipeline.readthedocs.org/en/latest/index.html
0
Prophet #
django-pipeline это форк django-compress'а и работает точно также, получая список css/js из конфигруационных файлов. Поправьте, если я ошибаюсь.
Нам это кажется достаточно неудобным, поэтому от django-compress'а мы отказались.
+3
frol #
Мы для переводов полей в моделях используем code.google.com/p/django-modeltranslation/
Глобальное отличие от hvad — поля, подлежащие переводу, указываются в отдельном файле translations.py (всё в одном файле, но при желании, конечно, можно разнести) и переводы хранятся в одной таблице с остальными полями.

translations.py выглядит примерно так:
from modeltranslation.translator import translator, TranslationOptions

from shop.models import Section, Category


class SectionTranslationOptions(TranslationOptions):
    fields = ('name', 'seo_keywords', 'seo_description', )


class CategoryTranslationOptions(TranslationOptions):
    fields = ('name', 'dative_name', 'instrumentative_name', 'all_plural_name', )


translator.register(Section, SectionTranslationOptions)
translator.register(Category, CategoryTranslationOptions)


А в админке это выглядит вот так:
0
mike_k #
А вкладки/переключатель языков в админке каким-то образом завязаны на modeltranslation? Чем сделаны?
0
frol #
В официальной доке django-modeltranslation всё написано.
from django.contrib import admin
from modeltranslation.admin import TranslationAdmin

class NewsAdmin(TranslationAdmin):
    list_display = ('title',)

admin.site.register(News, NewsAdmin)
0
mike_k #
Это понятно, приложением так и пользовался. Заинтересовал именно формат группировки доп. полей в админке на скриншоте — в виде вкладок.
0
frol #
Значит просто не всю доку прочитал.
0
mike_k #
Спасибо. Жутко торможу. (Вспомнил почему не применял: эти табы не работали с особенностями модифицированной админки конкретного проекта.)
0
magic4x #
По поводу сфинкса: очень рекомендую питоновскую апишку идущую в коробке. О ней почему-то часто забывают, а ведь она очень простая и приятная в использовании. Серьезно:
s = SphinxClient()
s.SetFilter('active', [1])
s.SetFilter('blog', [1111])
s.SetGroupBy('tags', SPH_GROUPBY_ATTR, "@count desc" )
s.AddQuery('', index=HABR_INDEX)
s.ResetGroupBy()

s.SetGroupBy('starred', SPH_GROUPBY_ATTR, "@count desc" )
s.AddQuery('', index=HABR_INDEX)

tags_facets, starred_facets = s.RunQueries()

Вот так вот просто две фасетки: тегов и тех у кого статья в избранных — причем в один мультизапрос, — это и быстрее и кода меньше, особенно когда нужно фасеток 5-10 собрать сразу, тогда можно просто for f in ['tags', 'followers', …].
В общем, я когда старый джанго-сфинкс смотрел так и не понял в чем его бонусы — апишка прозрачная, хорошо документированная (комменты).
+1
Prophet #
Преимущество как минимум в том, что конфиг не надо генерить руками.
0
mchl #
я так понимаю guardian вы заюзали после auhority? в последнем все никак даже админку непочинят, а патч в 1 строку. судя по всему пакеты очень похожи, стоит ли переходить на первый если в проекте уже используется последний?
0
Prophet #
auhority не использовали.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.