Пользователь
0,0
рейтинг
18 марта 2011 в 17:31

Разработка → Что будет в django 1.3

Релиз django 1.3 совсем скоро. Думаю, многие уже RC в продакшне используют. Но все равно, пробегусь еще раз по тому, что нас ждет, стараясь не скатиться в перевод release notes.


django.contrib.staticfiles


Теперь можно организовывать статику (картинки, js, css и т.д.) точно так же, как организуются шаблоны: держать ее в папке приложения (особенно полезно для отдельных django-приложений) или в папке проекта, переопределять часть файлов, оставляя другие нетронутыми, ссылаться на файлы, не заботясь о том, куда их пользователь поместит или где он хранятся (отдельный сервер? amazon s3?), не нужно больше «руками» эти файлы выискивать и копировать в правильное место.

Грязные хаки со статикой для админки теперь тоже, можно считать, в прошлом — если просто использовать django.contrib.staticfiles, проблем не будет.

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


В джанге теперь живет unittest2, django.test.TestCase наследуется от unittest2.TestCase. Это означает, что можно писать тесты для джанги, используя все новые фичи из unittest2. Например, можно писать тесты заранее и помечать их декоратором expectedFailure. Или указывать условия, при которых тесты должны пропускаться (например, тесты, специфичные для mysql и не должны проходить под sqlite). Или использовать новые assert'ы.

Конечно, раньше можно было поставить unittest2 и использовать его, но это не помогало, когда была нужна база и наследоваться нужно было от django.test.TestCase.

Появились также разные полезные мелочи вроде assertNumQueries.

ForeignKey


Ура, теперь при удалении объекта, на который кто-то ссылался через FK, ссылающиеся объекты не будут обязательно удалены. Можно настроить каскадное удаление, сброс в NULL или значение по умолчанию, вызов исключения, ничегонеделание (позволить базе самой решать).

Шаблоны


Часто писали
{% with foo as bar %}    
    {% include "my_template.inc.html" %}
{% endwith %}

или inclusion-теги для таких штук? Теперь это не обязательно, и кучу inclusion-тегов можно выкинуть будет:
{% include "my_template.inc.html" with bar=foo %}


+ можно загружать только отдельные теги из библиотек тегов; в url можно передавать переменные; тег with тоже упрощен; теги, созданные через simple_tag, научились принимать контекст.

Кеширование


Появилась поддержка нескольких кешей одновременно (например, часть данных можно хранить в localmem-кеше, часть — в memcached/базе, или для некоторых вещей использовать «умные» кеширующие бекенды с инвалидацией и защитой от одновременной повторной регенерации, для других — нет).

Кроме того, из разных сторонних приложений с кеширующими бекендами в джангу переползли полезные фичи: теперь из коробки есть поддержка глобального префикса (нужен, если несколько проектов используют 1 memcached, чтобы избежать конфликта ключей), версий кеша (обновил сайт, а в кеше старые данные лежат, которые теперь в неправильном формате? увеличь текущую версию кеша), преобразования ключей (нужна хитрая схема инвалидации? реализуй), поддержка pylibmc, кеширования для GET-запросов с параметрами.

Журналирование


Интеграция с питоновским logging теперь есть. В settings.py можно журналирование гибко настраивать. Отсылка email'ов по 500 ошибкам наконец тоже сделана через logging.

Вьюхи


Для написания вьюх появилась куча разных полезностей.

Вьюхи, основанные на классах.

Можно теперь писать вьюхи-классы. Для себя пока не понял, зачем они. Наверное, стоит использовать для каких-то «больших» штук, или когда какая-то сложная штуковина с замороченной логикой, которую нужно расширять в других местах (декларативный api? что-то уровня универсальной админки?). Стандартные generic views теперь переписаны на классах, чтобы их проще было расширять.

TemplateResponse

Для того, чтобы можно было расширять и обычные вьюхи-функции, в джанге теперь есть TemplateResponse. TemplateResponse — это ленивый HttpResponse, который рендерит результат (подставляет контекст в шаблон) только в самый последний момент. Если функция возвращает TemplateResponse, то у нее потом можно заменить шаблон, изменить (и прочитать) контекст, или вернуть совсем другое что-то (без накладных расходов на рендеринг исходного ответа). Эту штуку довольно легко пропустить в release notes и начать для гибкости наворачивать вьюхи на классах, поэтому пример:

# библиотека для работы с попугаями
# была написана профессором биологии в качестве материала к диссертации

from django.template.response import TemplateResponse
from parrots.models import Parrot

def parrot_list(request):
    parrots = Parrot.objects.all()
        
    # По умолчанию будет использоваться RequestContext. 
    # Полотна с render_to_template и хаки с direct_to_template теперь не нужны.
    return TemplateResponse(request, 'parrots.html', {'parrots': parrots})


# наш проект. 
# parrot_list делает много всего крутого и полезного (еще бы, профессор биологии писал), мы 
# хотим это повторно использовать, но некоторые вещи мечтаем поправить

import parrots.views

def parrot_list(request, color)
    # то, что функция возвращала по умолчанию
    response = parrots.views.parrot_list(request)

    # на данный момент шаблон еще не рендерился (TemplateResponse ленивый), 
    # к базе обращений тоже еще не было (QuerySet тоже ленивый)
    
    # меняем шаблон на свой - данные, с которыми он будет рендериться, пока теми же остаются
    response.template_name = 'my_parrots.html'

    # вытаскиваем профессорских попугаев 
    original_parrots = response.context_data['parrots']

    # фильтруем их по цвету, добавляем хозяина попугая сразу в выборку
    response.context_data['parrots'] = original_parrots.filter(color=color).select_related('owner')

    # еще что-нибудь пусть в контексте будет
    response.context_data['foo'] = 'bar'
    
    # вот теперь все настроили как хотели
    return response



Generic views теперь возвращают TemplateResponse по умолчанию, вьюхи из django.contrib.admin — тоже.
UPD: принял желаемое за действительное, вьюхи из django.contrib.admin TemplateResponse не возвращают! Тикет висит, но его к релизу не закоммитили.

django.shortcuts.render


# профессор не хочет, чтобы материалами его диссертации пользовались

from django.shortcuts import render

def parrot_list(request):
    parrots = Parrot.objects.all()      

    # render_to_response и direct_to_template теперь не нужны
    return render(request, 'parrots.html', {'parrots': parrots})



Это не все: кроме этих изменений, улучшена работа с i18n и l10n, из кода был убран весь мат, ну и еще много разных менее заметных изменений и архитектурных улучшений, о части которых можно почитать в release notes.
Коробов Михаил @kmike
карма
333,7
рейтинг 0,0
Пользователь
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (29)

  • +5
    Дождаться бы еще этого релиза. С декабря волынку тянут.
  • +1
    Я сделал параллельно перевод чейнджлога.
    Кстати, в примечаниях к релизу стоит обратить внимение на вещи, ломающие обратную совместимость кода, например, проверка CSRF-токенов и для ajax-видов. Из-за этого аяксовые формы без токена не будут обрабатываться. Это сделано для предотвращения особо хитрой CSRF-атаки.
  • 0
    Наконец-то для ForeignKey сделали выбор поведения при удалении. TemplateResponse тоже рулит, код чище будет.
  • 0
    >Вьюхи, основанные на классах.
    Весьма интересно.
    К примеру, я сейчас вьюхи оборачиваю в спец декораторы которые парсят get и post запросы, таким образом улучшается логика и наглядность приложения (пропадают нагромождения stuff-блоков кода).

    @login_required() #это стандартный
    @handle_get #а эти два кастомные
    @details_post
    def details(request, BlahInstance):
    pass

    Вьюхи на классах на мой взгляд будут намного гибче по сравнению с вышеприведённым примером. Но точно пока ничего сказать не могу, так как RC еще не смотрел. Интересный обзор, спасибо.
  • +1
    Наконец-то RequestContext можно будет удобно использовать из коробки! Хороший релиз, пойду обновляться.

    Вьюхи, основанные на классах

    Очень надеюсь, что это один из шагов к RESTификации джанги. Ибо для создания полноценных api сегодня приходится писать жуткие костыли.
    • +2
      Какие такие костыли?

      В любом случае, на новых CBV есть django-rest-framework.org/ (но все-таки CBV меня немного пугают Mixin'ами своими), мы django-tastypie используем для API, удачная штука.
      • 0
        Django rest framework использую уже больше месяца. Не особо удобен при большом количестве моделей и полей с моделями — приходится для каждой описывать разрешенные поля и запросы по многу раз etc. Сейчас для таких целей в каждой модели просто делаю кортеж allowed_fields — явный костыль. Еще он не сильно гибкий, возможностей мало, ведь разработка началась недавно. Хотя по сравнению с piston это рай.

        Да и бывает так, что в большинстве api resources просто дублируют вьюхи. Этого можно было бы избежать, если джанга умела REST из коробки, как рельсы, торнадо и многие современные веб-фреймворки.

        Tastypie вскопну, спасибо.
        • 0
          Под REST, по-моему, каждый разработчик что-то свое понимает) У кого-то это роутинг согласно методам http, у кого-то — соглашения о том, как иерархию url'ов строить, у кого-то главное — ссылки на ресурсы через uri, а не по первичным ключам, у кого-то — что о ресурсах, предоставляемых api, можно узнать, спросив об этом api.
  • 0
    Модуль для статичных файлов особенно радует. Его и для продакшена можно полноценно использовать?
    • +2
      Да, конечно. При разработке статика сама подхватывается, если подключить в urls.py проекта нужную строку, а для продакшна есть management-команда, которая статику собирает в одну папку (или куда угодно), а туда уже можно натравить веб-сервер.
      • 0
        Надеюсь оно не отдает объединенную статику через wsgi а просто складирует все в какую-то папочку?
        • 0
          В режиме разработки — отдает через wsgi, в продакшне — складывает в папочку через management-команду.
    • 0
      Пока его можно установить в качестве приложения, только вот компрессора работающего с ним я не видел.
      И да, автосбор статики — вещь!
      • 0
        Как минимум github.com/miracle2k/webassets и github.com/jezdez/django_compressor работают, если брать с гитхаба, а не с pypi.
        • 0
          Да, но там нужно вручную бандлы формировать, что не есть хорошо.
          • 0
            А что плохого? Все js-файлы в 1 сжимать (например, jquery + свой код одновременно) будет неправильно, т.к. при изменении какой-нибудь мелочи в коде приложения пользователям нужно будет и jquery тот же повторно скачивать. Или, например, зачем пользователяс фронтенда статика от джанговской админки. Лучше уж контроль над этим иметь по-моему.
            • 0
              Ну я же не говорил, что нужно обязательно ТАК это делать. Тем более джанга могла бы сама из респонса все вытаскивать и делать это нормально.
              • 0
                А как нужно делать? Я правда не понял) Если есть какая-то идея, которую можно формализовать и в виде кода реализовать, то можно ведь это сделать.
                • 0
                  Постараюсь объяснить идею, как я думал оно должно было бы работать.
                  Staticfiles ищет всю статику, которая есть в используемых приложениях (пока это не всегда работает, но это из-за свежести стандарта). Все это попадает в STATIC_ROOT.
                  Затем «мидлварь» берет Responce, ищет там все ссылки на статику (а они по умолчанию относительно, по стандартам фреймворка). Затем все это дело хешируется, и жмется в файл с соответствующим именем.
                  Отдельно хочется сказать только про разный набор запрашиваемых файлов, тут нужно просто подумать как хеш сделать, что-бы он при отсутствии нескольких файлов выдавал нужный файл.
                  Минус один — небольшая потеря в производительности…
                  • 0
                    django_compresor это вроде бы и делает, только ссылки на статику в шаблоне нужно явно тегом окружить (можно все сразу). Но это не обязательно плюс — в webassets писать кода меньше в результате. Или я опять не понял?
          • 0
            В webassets есть поддержка glob'ов, к тому же.
            • 0
              Не совсем понял, можете пояснить? Когда я его смотрел он мне статику отказывался от некоторых аппов находить (от тех которые были в виртуальном окружении).
              • 0
                С webassets все очень просто: в продакшне он сейчас жмет статику прямо из STATIC_ROOT, при разработке не жмет совсем. См. github.com/miracle2k/webassets/issues#issue/21.

                А glob — это в смысле что можно файлы по одному не перечислять, а звездочки и вопросики использовать.

                Если что-то не работает из этого — то, видимо, в баг-трекер лучше.
                • 0
                  Спасибо большое, потом посмотрю еще разок.
  • +1
    Еще один шаг в сторону значительного улучшения фреймворка:) Трижды ура! Правда затянули ужас как, с другой стороны оно того стоило, столько классных улучшений, на сколько я помню гораздо больше чем в 1.2.
    staticfiles, render и foreignkey явно не хватало. Пошел читать про остальное…
  • +1
    А /me вчера отрепортил баг и сегодня его уже пофиксили :-). code.djangoproject.com/changeset/15882
  • 0
    A roadmap for Django’s overall 2.x Python support, and eventual transition to Python 3.x, is currently being developed, and will be announced prior to the release of Django 1.3.

    Пока они будут тянуть кота за яйца — выйдет 4 пайтон
  • +1
    Прошу прощения за дезинформацию: вьюхи из django.contrib.admin не возвращают TemplateResponse, соответствующий тикет к релизу не закоммитили.

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