0,0
рейтинг
27 мая 2014 в 14:51

Разработка → Что нового нас ожидает в Django 1.7

В данном посте представлен обзор новшеств и особенностей популярного среди Python разработчиков фреймворка Django 1.7. Релиз позиционируется как сообществом, так и основными разработчиками — как наиболее значимый релиз, с момента выхода в свет Django 1.0.

image


Новшества в версии 1.7


Прекращение поддержки Python 2.6. Теперь поддерживается версия Python 2.7 и выше. Заявлена поддержка Python 3.4.
Добавлена нативная поддержка миграций непосредственно в сам фреймворк. Можно поблагодарить за это автора популярной батарейки South — Andrew Godwin-а.

Команда syncdb объявлена как устаревшая, и будет удалена в Django 1.9. До тех пор syncdb является псевдонимом команды migrate, которая обеспечивает как выполнение миграций, так и старое поведение syncdb.
Фикстуры initial_data более не инициализируются по умолчанию для приложений с миграциями. Предлагается воспользоваться загрузкой фикстур на уровне самих миграций.

Механизм загрузки приложения — был подвергнут полному рефакторингу. В результате можно отказаться от models.py, который ранее идентифицировал приложение и был обязательным.
Новые методы подклассов Field. Главная особенность — это обязательный метод deconstruct(). К сожалению в этом вина включения миграций в состав Django. Если Вы наследуетесь от стандартных полей и не переопределяете метод __init__, то заботиться Вам об этом не придется.

Появилась возможность вызовов QuerySet-ов напрямую из менеджера:

class FoodQuerySet(models.QuerySet):
    def pizzas(self):
        return self.filter(kind='pizza')

    def vegetarian(self):
        return self.filter(vegetarian=True)

class Food(models.Model):
    kind = models.CharField(max_length=50)
    vegetarian = models.BooleanField()
    objects = FoodQuerySet.as_manager()

Food.objects.pizzas().vegetarian()

Возможность указать необходимый менеджер при использовании связывания моделей:
class Blog(models.Model):
    pass

class Entry(models.Model):
    blog = models.ForeignKey(Blog)

    objects = models.Manager()  # Default Manager
    entries = EntryManager()    # Custom Manager

b = Blog.objects.get(id=1)
b.entry_set(manager='entries').all()


Новая система, для проверки проекта(System check), которая при запуске опеделяет проблемы и подсказывает что и как необходимо исправить. Для проверки, используется новая команда check, пришедшая на замену устаревшей команде validate.
Новый Prefetch для продвинутых операций prefetch_related. Теперь можно настроить предварительную выборку используя QuerySet-ы.

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

Курсор баз данных, теперь может использоваться в качестве контекст менеджера, что является сокращением для:

c = connection.cursor()
try:
    c.execute(...)
finally:
    c.close()


Возможность определения собственных типов поиска, для фильтрации при использовании ORM.

from django.db.models import IntegerField
from django.db.models import Transform

class AbsoluteValue(Transform):
    lookup_name = 'abs'

    def as_sql(self, qn, connection):
        lhs, params = qn.compile(self.lhs)
        return "ABS(%s)" % lhs, params

IntegerField.register_lookup(AbsoluteValue)

# Использование
Experiment.objects.filter(change__abs=27)

# В результате получим
# SELECT ... WHERE ABS("experiments"."change") = 27


Другие интересные изменения


django.contrib.admin
  • Появилась возможность реализовать собственные site_header, site_title, и index_title, без необходимости переопределения шаблона.
  • Метод ModelAdmin.get_fields() может быть преопределен, для настройки значений ModelAdmin.fields.
  • В дополнение к существующему синтаксису admin.site.register, можно использовать новый декоратор register().
  • Можно задать ModelAdmin.list_display_links = None, для того что бы отключить ссылки в grid-е
  • Для контроля кнопки «Посмотреть на сайте», можно определить свой ModelAdmin.view_on_site.
  • Возможность указать сортировку для ModelAdmin.list_display, подставляя дефис в admin_order_field.
  • Метод ModelAdmin.get_changeform_initial_data() может быть переопределен, для изменения данных формы.


django.contrib.auth
  • **kwargs передаваемые в email_user(), так же передаются и в send_mail().
  • декоратор permission_required() может получать на вход список разрешений или же только одно разрешение.
  • возможно переопределить новый метод AuthenticationForm.confirm_login_allowed(), для быстрой и легкой настройки политики авторизации.
  • django.contrib.auth.views.password_reset() принимает необязательный параметр html_email_template_name. Параметр используется для отправки html писем, при сбросе пароля .
  • добавлен метод AbstractBaseUser.get_session_auth_hash(). Если пользовательская модель унаследована от AbstractBaseUser, то изменение пароля пользователя приведет к сбросу его устаревших сесссий.


django.contrib.sites


E-mail
  • В send_mail() добавлен параметр html_message, для отправки сообщений типа text/html.
  • SMTP бекенд получил возможность установить параметр тайм-аута.


Загрузка файлов
  • Добавлен атрибут UploadedFile.content_type_extra, который содержит дополнительные параметры, передаваемые в заголовоке типа содержимого при загрузке файлов.
  • Новая настройка FILE_UPLOAD_DIRECTORY_PERMISSIONS позволяет задавать права на создаваемые директории при загрузке файлов. Ту же настройку непосредственно для файлов, выполняет FILE_UPLOAD_PERMISSIONS.
  • FileField.upload_to теперь является необязательным.


Формы
  • Textarea теперь включает атрибут max_length, если в модели определен max_length.
  • Field.choices позволяет задать value для пустого значения. По умолчанию "-------".
  • В формах в методе clean() более не требуется возвращать self.cleaned_data.
  • Появилась возможность удалить поля из формы, путем установки их имени в None.
  • Новый метод add_error() позволяет задавать ошибки для конкретных полей.
  • Добавлена возможность задавать и выводить ошибки к ограничителям вида unique, unique_for_date, и unique_together.


Интернационализация
  • Атрибут django.middleware.locale.LocaleMiddleware.response_redirect_class позволяет настроить переадресацию.
  • LocaleMiddleware хранит выбранный язык пользователем язык в _language. Получить доступ, можно используя константу LANGUAGE_SESSION_KEY.
  • Тег blocktrans удаляет атрибут trimmed. Данная опция удаляет символы новой строки с начала и до конца, обьеденяя их через пробел. Что удобно для генерации файлов локали.
  • Улучшен makemessages.
  • Были добавлены следущие языковые константы: LANGUAGE_COOKIE_AGE, LANGUAGE_COOKIE_DOMAIN and LANGUAGE_COOKIE_PATH.


Команды управления
  • Возможность отключить цветной вывод в консоль.
  • Добавлена возможность дампа данных с первичными ключами при сериализации.
  • Нет необходимости указывать название кеш таблицы при использовании createcachetable. Теперь Django это делает сама, с учетом настройки кеша в настройках проекта.
  • Команда runserver была улучшена. Теперь при установленном pyinotify, скорость релоада стала выше, и меньше потребляет батарею на ноутах. Так же сервер релоадиться при использовании команды compilemessages. Выводятся в консоль все запросы к статике, которые прежде фильтровались.


Модели
  • Новый метод QuerySet.update_or_create().
  • Новая Meta опция default_permissions, которая позволяет настроить операции создания/изменения/удаления.
  • Обнаружение OneToOneField при наследовании в абстрактных классах.
  • Добавлена возможность использовать None в качестве значения запроса при использовании iexact.
  • Возможность использования единого списка в index_together при указании одного набора полей(не список в списках).
  • Числовые поля теперь проверяются в зависимости от БД. Ранее могло приводить к ошибке.


Запросы и ответы
  • Новый атрибут HttpRequest.scheme определяет схему запроса (http или https).
  • redirect() поддерживает относительный URL.
  • Новый подкласс HttpResponse — JsonResponse.

Утилиты


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

Проголосовало 725 человек. Воздержалось 183 человека.

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

Руслан @gotlium
карма
15,7
рейтинг 0,0
DevOps
Реклама помогает поддерживать и развивать наши сервисы

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

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

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

  • +1
    Появилась возможность вызовов QuerySet-ов напрямую из менеджера:

    Давно пора. Клепать по менеджеру на каждый чих совсем не дело, особенно, когда это просится сделать через classmethod. Пытался пользоваться 1.7 — не договорился с миграцией, репорты висят, еще не фиксили на тот момент. И новый префетч клевый, да.
    • 0
      На тему QuerySet'ов, когда я ковырял исходники трансифекса, нашел там занятную штуку:
      class ChainerManager(models.Manager):
          """
          Reference: http://djangosnippets.org/snippets/562/
          """
          def __init__(self, qs_class=models.query.QuerySet):
              super(ChainerManager, self).__init__()
              self.queryset_class = qs_class
      
          def get_query_set(self):
              return self.queryset_class(self.model)
      
          def __getattr__(self, attr, *args):
              try:
                  return getattr(self.__class__, attr, *args)
              except AttributeError:
                  return getattr(self.get_query_set(), attr, *args)
      


      Что позволяло делать:

      NewsQuerySet(models.query.QuerySet):
          def live(self):
              return self.filter(state='published')
      
          def interesting(self):
              return self.filter(interesting=True)
      
      NewsItem(models.Model):
          objects = ChainerManager(NewsQuerySet)
      
      ChainerManager(NewsQuerySet).live().interesting()
      [<NewsItem: ...>]
      # ну или так:
      NewsItem.objects.filter().live().interesting()
      
      • +1
        Моя ленивый, моя лень забивать objects, да еще добавлять filter().live():

        class Boobs(models.Model):
            …
            @classproperty
            def medium(cls):
                return cls._default_manager.filter(…)
        
        Boobs.medium.latest()
        
  • +2
    > Курсор баз данных, теперь может использоваться в качестве контекст менеджера:
    А в коде, который написан под этим утверждением, context manager даже и не пахнет.
    • +1
      Спасибо. Дописал недостающую часть.
  • +9
    А как отечественные django-девелоперы относятся к грядущей замене терминов master/slave на leader / follower в django?
    github.com/django/django/pull/2692
  • +1
    Новая мидлварь django.contrib.sites.middleware.CurrentSiteMiddleware позволяет установливать текущий сайт при каждом запросе.

    А обещали, что sites сдохнет…

    Новый подкласс HttpResponse — JsonResponse.

    Наконец-то.
    • 0
      А зачем sites дохнуть?
  • 0
    Ребят, а есть ли хорошая/улучшенная поддержка нереляционных БД, вроде MongoDB? Чтобы админка работала сразу и без дополнительных установок плагинов
    • 0
      django-nosql only
  • 0
    Пример с кверисетами странный — я обычно то же самое дело в кастомном менеджере, унаследованном от штатного.
  • +1
    Печально, что сам South конфликтует с 1.7

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