Ещё 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

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 42

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

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

            Сейчас вся админка состоит из костылей. Часть кода в этой CMS, которая идет отдельным пакетом, часть кода в самом джанго приложении. Плюс куча наследованных класов с переопределением методов. Я уже подумываю переписать админку с использованием Pyramid, а затем и морду перенести на Pyramid.
              +2
              Проблема же не в Django, а в руках, должны понимать. Зачем отключать валидацию и что эта валидация у вас валидирует мне тоже не до конца понятно. Если форма это ModelForm, то валидацию можно определить/переопределить соответствующими методами.
                0
                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
                  Python без отступов — крууто :)

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

                    Жду конструктивных предложений, а не обсуждения рук.
                    • UFO just landed and posted this here
                0
                всё равно не понятно зачем отключать валидацию, ложные срабатывания?
                  0
                  Что за контора и что за CMS на Django?
                +4
                Дак сделайте же!
                  +3
                  Противные джанго-программисты, не хотят за вас писать код :)
                  0
                  Отлично, спасибо за новую пачку батареек, парочку новых нашел.

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

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

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

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

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

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

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

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

                                Так сделайте один общий набор, характерный для большинства страниц, а на этих нескольких уникальных страницах дополнительно подгружайте эти большие библиотеки (необязательно же всё запихнуть в 1 js файл)
                                  0
                                  Да, тоже вариант. Если не получится делать два сжатых файла средствами django-compressor, можно так и поступить. Спасибо.
                          +1
                          Можно сделать несколько минифицированных файлов, django-compressor это позволяет. Вообще, это самое правильное решение, когда есть универсальная сборка, общаяя для всех страниц + уникальные минисборки для отдельных.
                            0
                            Подскажите как, не нашёл этого в доках.
                              +2
                              Можно просто несколько тегов создать и всё:
                              {% 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
                                Так просто и очевидно, спасибо!
                          0
                          Мне для ассетов очень понравился django-pipeline.readthedocs.org/en/latest/index.html
                            0
                            django-pipeline это форк django-compress'а и работает точно также, получая список css/js из конфигруационных файлов. Поправьте, если я ошибаюсь.
                            Нам это кажется достаточно неудобным, поэтому от django-compress'а мы отказались.
                            +3
                            Мы для переводов полей в моделях используем 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
                              А вкладки/переключатель языков в админке каким-то образом завязаны на modeltranslation? Чем сделаны?
                                0
                                В официальной доке django-modeltranslation всё написано.
                                from django.contrib import admin
                                from modeltranslation.admin import TranslationAdmin
                                
                                class NewsAdmin(TranslationAdmin):
                                    list_display = ('title',)
                                
                                admin.site.register(News, NewsAdmin)
                                
                                  0
                                  Это понятно, приложением так и пользовался. Заинтересовал именно формат группировки доп. полей в админке на скриншоте — в виде вкладок.
                                    0
                                    Значит просто не всю доку прочитал.
                                      0
                                      Спасибо. Жутко торможу. (Вспомнил почему не применял: эти табы не работали с особенностями модифицированной админки конкретного проекта.)
                              0
                              По поводу сфинкса: очень рекомендую питоновскую апишку идущую в коробке. О ней почему-то часто забывают, а ведь она очень простая и приятная в использовании. Серьезно:
                              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
                                Преимущество как минимум в том, что конфиг не надо генерить руками.
                                0
                                я так понимаю guardian вы заюзали после auhority? в последнем все никак даже админку непочинят, а патч в 1 строку. судя по всему пакеты очень похожи, стоит ли переходить на первый если в проекте уже используется последний?
                                  0
                                  auhority не использовали.

                                Only users with full accounts can post comments. Log in, please.