Примечания к выпуску Django 1.2¶
*17 мая 2010 года.
Добро пожаловать в Django 1.2!
Почти год готовившийся Django 1.2 содержит впечатляющий список new features и множество исправлений ошибок. Эти заметки о выпуске охватывают новые возможности, а также важные изменения, о которых вы должны знать при переходе с Django 1.1 или более старых версий.
Обзор¶
Django 1.2 представляет несколько больших и важных новых возможностей, включая:
- Поддержка multiple database connections в одном экземпляре Django.
- Model validation вдохновлен валидацией форм в Django.
- Vastly improved protection against Cross-Site Request Forgery (CSRF).
- Новый user «messages» framework с поддержкой сообщений на основе cookie и сессий как для анонимных, так и для аутентифицированных пользователей.
- Крючки для object-level permissions, permissions for anonymous users и more flexible username requirements.
- Настройка отправки электронной почты через email backends.
- Новый «smart» if template tag, который поддерживает операторы сравнения.
Это только основные моменты; полная информация и полный список возможностей may be found below.
См.также
Django Advent Осветили выход Django 1.2 серией статей и учебников, в которых подробно рассматриваются некоторые из новых возможностей.
Там, где это возможно, эти функции были введены обратно совместимым образом в соответствии с политикой our API stability policy.
Однако несколько функций изменились таким образом, что для некоторых пользователей они окажутся обратно несовместимыми. Большими изменениями являются:
Поддержка Python 2.3 была прекращена. Смотрите полное примечание ниже.
Новая система защиты от CSRF не имеет обратной совместимости со старой системой. Пользователи старой системы не будут затронуты до тех пор, пока старая система не будет удалена в Django 1.4.
Однако переход на новую систему защиты от CSRF требует нескольких важных изменений, несовместимых с обратной стороной, которые подробно описаны ниже в CSRF Protection.
Авторы пользовательских подклассов
Field
должны знать, что у ряда методов был изменен прототип, подробно описанный ниже в разделе get_db_prep_*() methods on Field.Внутреннее устройство тегов шаблонов несколько изменилось; авторы пользовательских тегов шаблонов, которые должны хранить состояние (например, пользовательские теги потока управления), должны убедиться, что их код следует новым правилам для stateful template tags.
Декораторы
user_passes_test()
,login_required()
иpermission_required()
изdjango.contrib.auth
применяются только к функциям и больше не работают с методами. Есть простое однострочное исправление detailed below.
Повторимся, это только основные возможности, которые затронут большинство пользователей. Пользователям, переходящим с предыдущих версий Django, настоятельно рекомендуется ознакомиться с полным списком backwards-incompatible changes и списком deprecated features.
Совместимость с Python¶
Хотя это не новая функция, важно отметить, что Django 1.2 вводит первое изменение в нашей политике совместимости с Python с момента первого публичного дебюта Django. Предыдущие выпуски Django тестировались и поддерживались на версиях Python 2.x, начиная с 2.3; Django 1.2, однако, прекращает официальную поддержку Python 2.3. Таким образом, минимальная версия Python, необходимая для Django, теперь составляет 2.4, а Django тестируется и поддерживается на Python 2.4, 2.5 и 2.6, и будет поддерживаться на еще не вышедшем Python 2.7.
Это изменение должно затронуть лишь небольшое количество пользователей Django, поскольку большинство производителей операционных систем сегодня поставляют Python 2.4 или более новую версию по умолчанию. Однако если вы все еще используете Python 2.3, вам придется придерживаться Django 1.1, пока вы не сможете перейти на новую версию; согласно our support policy, Django 1.1 будет продолжать получать поддержку безопасности до выхода Django 1.3.
Дорожная карта для общей поддержки Python 2.x в Django и возможного перехода на Python 3.x в настоящее время разрабатывается и будет объявлена до выхода Django 1.3.
Что нового в Django 1.2¶
Поддержка нескольких баз данных¶
Django 1.2 добавляет возможность использовать more than one database в вашем проекте Django. Запросы к конкретной базе данных могут быть сделаны с помощью метода using()
на объектах QuerySet
. Отдельные объекты могут быть сохранены в конкретной базе данных путем предоставления аргумента using
при вызове save()
.
Валидация модели¶
Экземпляры модели теперь поддерживают validating their own data, а поля модели и формы теперь принимают настраиваемые списки validators, определяющие многоразовое, инкапсулированное поведение валидации. Обратите внимание, однако, что валидация по-прежнему должна выполняться явно. Простое обращение к методу save()
экземпляра модели не приведет к проверке данных экземпляра.
Улучшенная защита от CSRF¶
Django теперь имеет значительно улучшенную защиту от Cross-Site Request Forgery (CSRF) attacks. Этот тип атаки возникает, когда вредоносный сайт содержит ссылку, кнопку формы или какой-либо JavaScript, предназначенный для выполнения некоторого действия на вашем сайте, используя учетные данные вошедшего в систему пользователя, который посещает вредоносный сайт в своем браузере. Также рассматривается смежный тип атаки, «login CSRF», когда атакующий сайт обманывает браузер пользователя, заставляя его войти на сайт с чужими учетными данными.
Рамки сообщений¶
Django теперь включает надежный и настраиваемый messages framework со встроенной поддержкой обмена сообщениями на основе cookie и сессий, как для анонимных, так и для аутентифицированных клиентов. Фреймворк сообщений заменяет устаревший API пользовательских сообщений и позволяет временно хранить сообщения в одном запросе и извлекать их для отображения в последующем запросе (обычно следующем).
Разрешения на уровне объекта¶
Добавлена основа для указания разрешений на уровне каждого объекта. Хотя в ядре это не реализовано, пользовательский бэкенд аутентификации может предоставить такую реализацию, и она будет использоваться django.contrib.auth.models.User
. Дополнительную информацию см. в authentication docs.
Разрешения для анонимных пользователей¶
Если вы предоставите пользовательский бэкенд auth с параметром supports_anonymous_user
, установленным на True
, AnonymousUser будет проверять бэкенд на наличие разрешений, как это уже делал User. Это полезно для централизации обработки разрешений - приложения всегда могут делегировать вопрос о том, разрешено ли что-то или нет, бэкенду авторизации/аутентификации. Более подробную информацию см. в authentication docs.
Ослабленные требования к именам пользователей¶
Встроенное поле User
модели username
теперь допускает более широкий диапазон символов, включая @
, +
, .
и -
.
Бэкенды электронной почты¶
Теперь вы можете configure the way that Django sends email. Вместо использования SMTP для отправки всей электронной почты, теперь вы можете выбрать настраиваемый почтовый бэкенд для отправки сообщений. Если ваш хостинг-провайдер использует песочницу или какую-то другую не-SMTP технику для отправки почты, теперь вы можете сконструировать почтовый бэкенд, который позволит стандартному mail sending methods Django использовать эти средства.
Это также облегчает отладку отправки почты. Django поставляется с реализацией бэкенда, которая позволяет вам отправлять почту на file, на console, или на memory. Вы даже можете настроить всю электронную почту на thrown away.
«Умный» if
тег¶
Тег if
был усовершенствован и стал намного мощнее. Во-первых, мы добавили поддержку операторов сравнения. Больше вам не придется набирать:
{% ifnotequal a b %}
...
{% endifnotequal %}
Теперь вы можете это сделать:
{% if a != b %}
...
{% endif %}
На самом деле больше нет причин использовать {% ifequal %}
или {% ifnotequal %}
, если только вы не ностальгирующий тип.
Поддерживаются следующие операторы: ==
, !=
, <
, >
, <=
, >=
, in
и not in
, которые работают как операторы Python, в дополнение к and
, or
и not
, которые уже поддерживались.
Кроме того, теперь в выражении if
можно использовать фильтры. Например:
<div
{% if user.email|lower == message.recipient|lower %}
class="highlight"
{% endif %}
>{{ message }}</div>
Кэширование шаблонов¶
В предыдущих версиях Django каждый раз, когда вы рендерили шаблон, он перезагружался с диска. В Django 1.2 вы можете использовать cached template loader для загрузки шаблонов один раз, а затем кэшировать результат для каждого последующего рендеринга. Это может привести к значительному повышению производительности, если ваши шаблоны разбиты на множество маленьких подшаблонов (с помощью тегов {% extends %}
или {% include %}
).
Как побочный эффект, теперь стало намного проще поддерживать языки шаблонов, не относящиеся к Django.
Загрузчики шаблонов на основе классов¶
В рамках изменений, внесенных для внедрения Template caching и следуя общей тенденции в Django, API загрузчиков шаблонов был изменен для использования механизмов загрузки шаблонов, инкапсулированных в классы Python, в отличие от функций, единственного метода, доступного до Django 1.1.
Все загрузчики шаблонов shipped with Django были перенесены на новый API, но они по-прежнему реализуют API на основе функций, и механизм ядра шаблонов по-прежнему принимает загрузчики на основе функций (встроенные или сторонние), поэтому нет необходимости изменять ваши настройки TEMPLATE_LOADERS
в существующих проектах, все будет работать, если вы оставите их нетронутыми до релиза Django 1.3 включительно.
Если вы разработали свои собственные пользовательские загрузчики шаблонов, мы рекомендуем рассмотреть возможность их переноса на реализацию на основе классов, поскольку код обратной совместимости с загрузчиками на основе функций начинает свой процесс обесценивания в Django 1.2 и будет удален в Django 1.4. Описание API, которые должны реализовывать классы загрузчиков, есть в справке по API шаблона, также вы можете изучить исходный код загрузчиков, поставляемых с Django.
Натуральные ключи в светильниках¶
Теперь приспособления могут ссылаться на удаленные объекты, используя Натуральные ключи. Эта схема поиска является альтернативой обычным ссылкам на объекты в фикстуре, основанным на первичном ключе, улучшая читабельность и решая проблемы, связанные со ссылками на объекты, значение первичного ключа которых не может быть предсказуемым или известным.
Быстрый отказ при проведении испытаний¶
Как подкоманда test
из django-admin.py
, так и сценарий runtests.py
, используемый для запуска собственного набора тестов Django, теперь поддерживают опцию --failfast
. Когда эта опция указана, она заставляет программу запуска тестов завершать работу после обнаружения сбоя вместо того, чтобы продолжать выполнение теста. Кроме того, была улучшена обработка Ctrl-C
во время выполнения теста, чтобы вызвать изящный выход из теста, который сообщает подробности о тестах, которые были запущены до прерывания.
BigIntegerField
¶
Модели теперь могут использовать 64-битный тип BigIntegerField
.
Улучшенная локализация¶
В Django internationalization framework добавлено форматирование и обработка форм с учетом локали. Это означает, что, если эта функция включена, даты и числа в шаблонах будут отображаться с использованием формата, заданного для текущей локали. Django также будет использовать локализованные форматы при разборе данных в формах. Более подробную информацию смотрите в Локализация формата.
readonly_fields
в ModelAdmin
¶
django.contrib.admin.ModelAdmin.readonly_fields
было добавлено для включения нередактируемых полей на страницах добавления/изменения моделей и инлайнов. Поля и вычисляемые значения могут отображаться рядом с редактируемыми полями.
Настраиваемая подсветка синтаксиса¶
Теперь вы можете использовать переменную окружения DJANGO_COLORS
для изменения или отключения цветов, используемых django-admin.py
для обеспечения syntax highlighting.
Синдикация фидов как представлений¶
Syndication feeds теперь можно использовать непосредственно как представления в ваших URLconf. Это означает, что вы можете полностью контролировать структуру URL ваших фидов. Как и любое другое представление, представления фидов передаются объекту request
, поэтому вы можете делать все, что обычно делаете с представлением, например, контролировать доступ на основе пользователя или сделать фид именованным URL.
GeoDjango¶
Наиболее значительной новой функцией GeoDjango в версии 1.2 является поддержка нескольких пространственных баз данных. В результате, следующие spatial database backends теперь включены:
django.contrib.gis.db.backends.postgis
django.contrib.gis.db.backends.mysql
django.contrib.gis.db.backends.oracle
django.contrib.gis.db.backends.spatialite
GeoDjango теперь поддерживает богатые возможности, добавленные в релизе PostGIS 1.5. Новые возможности включают поддержку geography type и включение distance queries с неточечными геометриями в географических системах координат.
Была добавлена поддержка полей трехмерной геометрии, которую можно включить, установив ключевое слово dim
на 3 в вашем GeometryField
. В рамках этой функции были добавлены агрегат Extent3D
и метод extent3d()
GeoQuerySet
.
Методы force_rhr()
, reverse_geom()
и geohash()
GeoQuerySet
являются новыми.
Интерфейс GEOS был обновлен для использования потокобезопасных функций библиотеки C, когда они доступны на платформе.
Интерфейс GDAL теперь позволяет пользователю устанавливать spatial_filter
для функций, возвращаемых при итерации по Layer
.
Наконец, GeoDjango’s documentation теперь включен в Django’s и больше не размещается отдельно на geodjango.org.
Новые символы спецификатора формата тега шаблона now
: c
и u
.¶
Аргумент now
обзавелся двумя новыми символами формата: c
для указания, что значение времени даты должно быть отформатировано в формате ISO 8601, и u
, позволяющий выводить микросекундную часть значения времени или времени.
Они также доступны в других частях, таких как фильтры шаблонов date
и time
, библиотека тегов шаблонов humanize
и новый фреймворк format localization.
Изменения в 1.2 с обратной совместимостью¶
Там, где это возможно, новые возможности были введены с обратной совместимостью в соответствии с политикой our API stability policy. Это означает, что практически весь существующий код, который работал с Django 1.1, будет продолжать работать с Django 1.2; такой код, однако, начнет выдавать предупреждения (подробности см. ниже).
Однако несколько функций изменились таким образом, что для некоторых пользователей сразу же возникнет обратная несовместимость. Эти изменения подробно описаны ниже.
Защита от CSRF¶
Мы внесли большие изменения в способ работы защиты от CSRF, подробно описанные в the CSRF documentation. Вот основные изменения, о которых вы должны знать:
CsrfResponseMiddleware
иCsrfMiddleware
были устаревшими и будут полностью удалены в Django 1.4, в пользу тега шаблона, который должен быть вставлен в формы.Все приложения contrib используют декоратор
csrf_protect
для защиты представления. Это требует использования тега шаблонаcsrf_token
в шаблоне. Если вы использовали пользовательские шаблоны для представлений contrib, вы ДОЛЖНЫ ПРОЧИТАТЬ ИНСТРУКЦИИ ПО ОБНОВЛЕНИЮ, чтобы исправить эти шаблоны.Документация удалена
Примечания по обновлению были удалены в текущей документации Django. Пожалуйста, обратитесь к документации по Django 1.3 и старше, чтобы найти эти инструкции.
CsrfViewMiddleware
по умолчанию включается вMIDDLEWARE_CLASSES
. Это включает защиту CSRF по умолчанию, поэтому представления, принимающие POST-запросы, должны быть написаны для работы с промежуточным ПО. Инструкции о том, как это сделать, можно найти в документации по CSRF.Весь CSRF переехал из contrib в core (с обратно совместимыми импортами в старых местах, которые устарели и перестанут поддерживаться в Django 1.4).
get_db_prep_*()
методы на Field
¶
До версии Django 1.2 пользовательское поле Field
имело возможность определения нескольких функций для поддержки преобразования значений Python в значения, совместимые с базой данных. Пользовательское поле могло выглядеть примерно так:
class CustomModelField(models.Field):
# ...
def db_type(self):
# ...
def get_db_prep_save(self, value):
# ...
def get_db_prep_value(self, value):
# ...
def get_db_prep_lookup(self, lookup_type, value):
# ...
В версии 1.2 эти три метода претерпели изменения в прототипе, и были введены два дополнительных метода:
class CustomModelField(models.Field):
# ...
def db_type(self, connection):
# ...
def get_prep_value(self, value):
# ...
def get_prep_lookup(self, lookup_type, value):
# ...
def get_db_prep_save(self, value, connection):
# ...
def get_db_prep_value(self, value, connection, prepared=False):
# ...
def get_db_prep_lookup(self, lookup_type, value, connection, prepared=False):
# ...
Эти изменения необходимы для поддержки нескольких баз данных – db_type
и get_db_prep_*
больше не могут делать никаких предположений относительно базы данных, для которой выполняется подготовка. Аргумент connection
теперь предоставляет методам подготовки конкретное соединение, для которого подготавливается значение.
Два новых метода существуют для того, чтобы отличать общие требования к подготовке данных от требований, специфичных для базы данных. Аргумент prepared
используется для указания методам подготовки базы данных, была ли выполнена общая подготовка значения. Если неподготовленное (т.е. prepared=False
) значение предоставляется вызовам get_db_prep_*()
, они должны вызвать соответствующие вызовы get_prep_*()
для выполнения общей подготовки данных.
Мы предоставили функции преобразования, которые прозрачно конвертируют функции, придерживающиеся старого прототипа, в функции, совместимые с новым прототипом. Однако эти функции преобразования будут удалены в Django 1.4, поэтому вам следует как можно скорее обновить ваши определения Field
для использования нового прототипа.
Если ваши методы get_db_prep_*()
не использовали подключение к базе данных, то вы можете перейти на новую версию, переименовав get_db_prep_value()
в get_prep_value()
и get_db_prep_lookup()
в get_prep_lookup()
. Если вам требуются преобразования, специфичные для базы данных, то вам необходимо предоставить реализацию get_db_prep_*
, которая использует аргумент connection
для разрешения значений, специфичных для базы данных.
Теги шаблона Stateful¶
Теги шаблонов, которые хранят состояние рендеринга в своем подклассе Node
, всегда были уязвимы к потоковой безопасности и другим проблемам; однако, начиная с Django 1.2, они также могут вызвать проблемы при использовании с новым cached template loader.
Все встроенные теги шаблонов Django безопасны для использования с кэшированным загрузчиком, но если вы используете пользовательские теги шаблонов, полученные из сторонних пакетов или из вашего собственного кода, вы должны убедиться, что реализация Node
для каждого тега является потокобезопасной. Для получения дополнительной информации см. раздел template tag thread safety considerations.
Вам также может понадобиться обновить ваши шаблоны, если вы полагались на то, что реализация тегов шаблонов Django не является потокобезопасной. Наиболее вероятно, что тег cycle
может быть затронут таким образом, особенно когда он используется в сочетании с тегом include
. Рассмотрим следующий фрагмент шаблона:
{% for object in object_list %}
{% include "subtemplate.html" %}
{% endfor %}
с subtemplate.html
, которая гласит:
{% cycle 'even' 'odd' %}
Используя непотокобезопасный рендерер, существовавший до версии Django 1.2, это выведет:
even odd even odd ...
Используя потокобезопасный рендерер Django 1.2, вы получите:
even even even even ...
Это происходит потому, что каждая визуализация тега include
является независимой визуализацией. Когда тег cycle
не был потокобезопасным, состояние тега cycle
могло просочиться между несколькими рендерингами одного и того же include
. Теперь, когда тег cycle
стал потокобезопасным, эта утечка больше не происходит.
user_passes_test
, login_required
и permission_required
.¶
django.contrib.auth.decorators
предоставляет декораторы login_required
, permission_required
и user_passes_test
. Ранее было возможно использовать эти декораторы как на функциях (где первый аргумент - „request“), так и на методах (где первый аргумент - „self“, а второй - „request“). К сожалению, в коде, поддерживающем это, были обнаружены недостатки: он работает только в ограниченных обстоятельствах и выдает ошибки, которые очень трудно отладить, когда он не работает.
По этой причине поведение «автоматической адаптации» было удалено, и если вы используете эти декораторы в методах, вам придется вручную применить django.utils.decorators.method_decorator()
, чтобы преобразовать декоратор в тот, который работает с методами. Например, вы измените код следующим образом:
class MyClass(object):
@login_required
def my_view(self, request):
pass
к этому:
from django.utils.decorators import method_decorator
class MyClass(object):
@method_decorator(login_required)
def my_view(self, request):
pass
или:
from django.utils.decorators import method_decorator
login_required_m = method_decorator(login_required)
class MyClass(object):
@login_required_m
def my_view(self, request):
pass
Для тех из вас, кто следит за магистралью разработки, это изменение также относится к другим декораторам, введенным с версии 1.1, включая csrf_protect
, cache_control
и все, что создано с помощью decorator_from_middleware
.
if
тег меняется¶
В связи с новыми возможностями тега шаблона if
, он больше не принимает „and“, „or“ и „not“ в качестве допустимых имен переменных. Ранее эти строки могли использоваться в качестве имен переменных. Теперь всегда соблюдается статус ключевого слова, и код шаблона, такой как {% if not %}
или {% if and %}
будет отбрасывать TemplateSyntaxError
. Кроме того, in
является новым ключевым словом и поэтому не является допустимым именем переменной в этом теге.
LazyObject
¶
LazyObject
- это недокументированный, но часто используемый класс, используемый для ленивого обертывания других объектов неизвестного типа.
В Django 1.1 и более ранних версиях он обрабатывал интроспекцию нестандартным образом, в зависимости от обернутых объектов, реализующих публичный метод с именем get_all_members()
. Поскольку это могло легко привести к столкновению имен, он был изменен на использование стандартного метода интроспекции Python, включающего __members__
и __dir__()
.
Если вы использовали LazyObject
в своем собственном коде и реализовали метод get_all_members()
для обернутых объектов, вам нужно будет сделать пару изменений:
Во-первых, если ваш класс не имеет специальных требований к интроспекции (т.е. вы не реализовали __getattr__()
или другие методы, позволяющие обнаружить атрибуты, не обнаруживаемые обычными механизмами), вы можете просто удалить метод get_all_members()
. Реализация по умолчанию LazyObject
сделает все правильно.
Если у вас более сложные требования к интроспекции, сначала переименуйте метод get_all_members()
в __dir__()
. Это стандартный метод интроспекции для Python 2.6 и выше. Если вам требуется поддержка версий Python более ранних, чем 2.6, добавьте в класс следующий код:
__members__ = property(lambda self: self.__dir__())
__dict__
на экземплярах модели¶
Исторически сложилось так, что атрибут __dict__
экземпляра модели содержал только атрибуты, соответствующие полям модели.
Для поддержки нескольких конфигураций баз данных в Django 1.2 добавлен атрибут _state
для экземпляров объектов. Этот атрибут появится в __dict__
для экземпляра модели. Если ваш код полагается на итерацию по __dict__
для получения списка полей, вы должны быть готовы обрабатывать или отфильтровывать атрибут _state
.
Код статуса завершения работы программы тестирования¶
Код состояния выхода из программы запуска тестов (tests/runtests.py
и python manage.py test
) больше не отражает количество проваленных тестов, поскольку провал 256 или более тестов приводил к неправильному коду состояния выхода. Теперь код состояния выхода для бегунка тестирования равен 0 для успеха (нет неудачных тестов) и 1 для любого количества неудачных тестов. При необходимости количество неудачных тестов можно найти в конце выходных данных программы запуска тестов.
Кодировка файлов cookie¶
Для исправления ошибок с cookies в Internet Explorer, Safari и, возможно, других браузерах, наша кодировка значений cookies была изменена таким образом, что запятая и точка с запятой рассматриваются как небезопасные символы и поэтому кодируются как \054
и \073
соответственно. Это может привести к обратной несовместимости, особенно если вы храните запятую или точку с запятой в файлах cookie и имеете код JavaScript, который анализирует и манипулирует значениями cookie на стороне клиента.
ModelForm.is_valid()
и ModelForm.errors
.¶
Большая часть работы по валидации для ModelForms была перенесена на уровень модели. В результате, при первом вызове ModelForm.is_valid()
, обращении к ModelForm.errors
или другом запуске проверки формы, ваша модель будет очищена на месте. Раньше это преобразование происходило при сохранении модели. Если вам нужен немодифицированный экземпляр вашей модели, вы должны передать его копию конструктору ModelForm
.
BooleanField
на MySQL¶
В предыдущих версиях Django, BooleanField
модели под MySQL возвращало свое значение как 1
или 0
, вместо True
или False
; для большинства людей это не было проблемой, потому что bool
является подклассом int
в Python. В Django 1.2, однако, BooleanField
на MySQL корректно возвращает настоящий bool
. Единственный случай, когда это может стать проблемой, это если вы ожидали, что repr
из BooleanField
выведет 1
или 0
.
Изменения в интерпретации max_num
в FormSets¶
В рамках усовершенствований, внесенных в работу с наборами форм, значение и интерпретация параметра max_num
по умолчанию для функций django.forms.formsets.formset_factory() и django.forms.models.modelformset_factory() несколько изменились. Это изменение также влияет на то, как аргумент max_num
используется для встроенных объектов администратора.
Ранее значением по умолчанию для max_num
было 0
(ноль). Наборы форм затем использовали булево значение max_num
, чтобы определить, должно ли быть наложено ограничение на количество создаваемых форм. Значение по умолчанию 0
означало, что количество форм в FormSet по умолчанию не ограничено.
Начиная с версии 1.2, значение по умолчанию для max_num
было изменено на None
, и FormSets будет различать значения None
и 0
. Значение None
указывает, что никаких ограничений на количество форм не должно быть; значение 0
указывает, что должно быть введено максимум 0 форм. Это не обязательно означает, что ни одна форма не будет отображаться - см. подробнее ModelFormSet documentation.
Если вы вручную указывали значение 0
для max_num
, вам необходимо обновить определения FormSet и/или администратора.
email_re
¶
Недокументированное регулярное выражение для проверки адресов электронной почты было перемещено из django.form.fields
в django.core.validators
. Вам нужно будет обновить импорт, если вы его используете.
Функции, устаревшие в версии 1.2¶
Наконец, в Django 1.2 устарели некоторые функции из предыдущих релизов. Эти функции все еще поддерживаются, но будут постепенно отменяться в течение следующих нескольких циклов выпуска.
Код, использующий любую из перечисленных ниже возможностей, вызовет предупреждение PendingDeprecationWarning
в Django 1.2. По умолчанию это предупреждение молчит, но его можно включить с помощью модуля Python warnings
, или запустив Python с флагом -Wd
или -Wall
.
В Django 1.3 эти предупреждения станут DeprecationWarning
, что не является молчанием. В Django 1.4 поддержка этих функций будет полностью удалена.
См.также
Более подробную информацию можно найти в документации Django’s release process и в нашей deprecation timeline.`.
Указание баз данных¶
До версии Django 1.2, Django использовал ряд настроек для контроля доступа к одной базе данных. В Django 1.2 появилась поддержка нескольких баз данных, в результате чего изменился способ определения настроек базы данных.
Любой существующий файл настроек Django будет продолжать работать как ожидается до версии Django 1.4. До этого времени настройки базы данных старого стиля будут автоматически переведены в формат нового стиля.
В старом формате (до версии 1.2) в файле настроек было несколько параметров DATABASE_
. Например:
DATABASE_NAME = 'test_db'
DATABASE_ENGINE = 'postgresql_psycopg2'
DATABASE_USER = 'myusername'
DATABASE_PASSWORD = 's3krit'
Теперь эти настройки находятся в словаре с именем DATABASES
. Каждый элемент в словаре соответствует одному соединению с базой данных, а имя 'default'
описывает соединение с базой данных по умолчанию. Имена настроек также были сокращены. Предыдущий пример настроек теперь выглядит следующим образом:
DATABASES = {
'default': {
'NAME': 'test_db',
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'USER': 'myusername',
'PASSWORD': 's3krit',
}
}
Это влияет на следующие настройки:
Старая обстановка | Новая установка |
---|---|
DATABASE_ENGINE |
ENGINE |
DATABASE_HOST |
HOST |
DATABASE_NAME |
NAME |
DATABASE_OPTIONS |
OPTIONS |
DATABASE_PASSWORD |
PASSWORD |
DATABASE_PORT |
PORT |
DATABASE_USER |
USER |
TEST_DATABASE_CHARSET |
TEST_CHARSET |
TEST_DATABASE_COLLATION |
TEST_COLLATION |
TEST_DATABASE_NAME |
TEST_NAME |
Эти изменения также необходимы, если вы вручную создали соединение с базой данных, используя DatabaseWrapper()
из выбранного вами бэкенда базы данных.
В дополнение к изменению структуры, Django 1.2 удаляет специальную обработку для встроенных бэкендов баз данных. Теперь все бэкенды баз данных должны быть указаны полным именем модуля (т.е. django.db.backends.postgresql_psycopg2
, а не просто postgresql_psycopg2
).
postgresql
бэкенд базы данных¶
Библиотека psycopg1
не обновлялась с октября 2005 года. В результате, бэкенд базы данных postgresql
, использующий эту библиотеку, был устаревшим.
Если в настоящее время вы используете бэкенд postgresql
, вам следует перейти на использование бэкенда postgresql_psycopg2
. Чтобы обновить код, установите библиотеку psycopg2
и измените настройку ENGINE
на использование django.db.backends.postgresql_psycopg2
.
CSRF response-rewriting middleware¶
CsrfResponseMiddleware
, промежуточное программное обеспечение, которое автоматически вставляло CSRF-токены в формы POST
на исходящих страницах, было устаревшим в пользу метода тегов шаблона (см. выше), и будет полностью удалено в Django 1.4. CsrfMiddleware
, который включает в себя функциональность CsrfResponseMiddleware
и CsrfViewMiddleware
, также был устаревшим.
Кроме того, модуль CSRF перешел из contrib в core, и старые импорты устарели, как описано в примечаниях к обновлению.
Документация удалена
Примечания по обновлению были удалены в текущей документации Django. Пожалуйста, обратитесь к документации по Django 1.3 и старше, чтобы найти эти инструкции.
SMTPConnection
¶
Класс SMTPConnection
был упразднен в пользу общего API бэкенда электронной почты. Старый код, который явно инстанцировал экземпляр SMTPConnection:
from django.core.mail import SMTPConnection
connection = SMTPConnection()
messages = get_notification_email()
connection.send_messages(messages)
…теперь следует вызвать get_connection()
для создания общего почтового соединения:
from django.core.mail import get_connection
connection = get_connection()
messages = get_notification_email()
connection.send_messages(messages)
В зависимости от значения параметра EMAIL_BACKEND
, это может не вернуть SMTP-соединение. Если вам явно требуется SMTP-соединение для отправки электронной почты, вы можете явно запросить SMTP-соединение:
from django.core.mail import get_connection
connection = get_connection('django.core.mail.backends.smtp.EmailBackend')
messages = get_notification_email()
connection.send_messages(messages)
Если ваш вызов для построения экземпляра SMTPConnection
потребовал дополнительных аргументов, эти аргументы могут быть переданы вызову get_connection()
:
connection = get_connection('django.core.mail.backends.smtp.EmailBackend', hostname='localhost', port=1234)
API пользовательских сообщений¶
API для хранения сообщений в модели пользователя Message
(через user.message_set.create
) теперь устарел и будет удален в Django 1.4 в соответствии со стандартом release process.
Чтобы обновить код, необходимо заменить все экземпляры this:
user.message_set.create('a message')
..:
from django.contrib import messages
messages.add_message(request, messages.INFO, 'a message')
Кроме того, если вы используете этот метод, вам необходимо заменить следующее:
for message in user.get_and_delete_messages():
...
…с:
from django.contrib import messages
for message in messages.get_messages(request):
...
Для получения дополнительной информации см. полный текст messages documentation. Вы должны немедленно начать обновлять свой код для использования нового API.
Вспомогательные функции формата даты¶
django.utils.translation.get_date_formats()
и django.utils.translation.get_partial_date_formats()
были устаревшими в пользу соответствующих вызовов django.utils.formats.get_format()
, который является локально-ориентированным, когда USE_L10N
установлен в True
, и возвращается к настройкам по умолчанию, если установлен в False
.
Чтобы получить различные форматы дат, вместо этого напишите так:
from django.utils.translation import get_date_formats
date_format, datetime_format, time_format = get_date_formats()
…использовать:
from django.utils import formats
date_format = formats.get_format('DATE_FORMAT')
datetime_format = formats.get_format('DATETIME_FORMAT')
time_format = formats.get_format('TIME_FORMAT')
Или при прямом форматировании значения даты:
from django.utils import formats
value_formatted = formats.date_format(value, 'DATETIME_FORMAT')
То же самое относится и к глобальным файлам, находящимся в django.forms.fields
:
DEFAULT_DATE_INPUT_FORMATS
DEFAULT_TIME_INPUT_FORMATS
DEFAULT_DATETIME_INPUT_FORMATS
Используйте django.utils.formats.get_format()
для получения соответствующих форматов.
Бегунки для тестирования на основе функций¶
Django 1.2 изменяет инструменты прогона тестов, чтобы использовать подход, основанный на классах. Старые средства запуска тестов, основанные на функциях, все еще будут работать, но должны быть обновлены для использования нового class-based runners.
Feed
в django.contrib.syndication.feeds
¶
Класс django.contrib.syndication.feeds.Feed
был заменен классом django.contrib.syndication.views.Feed
. Старый класс feeds.Feed
является устаревшим и будет удален в Django 1.4.
Новый класс имеет почти идентичный API, но позволяет использовать экземпляры в качестве представлений. Например, рассмотрим использование старой структуры в следующем URLconf:
from django.conf.urls.defaults import *
from myproject.feeds import LatestEntries, LatestEntriesByCategory
feeds = {
'latest': LatestEntries,
'categories': LatestEntriesByCategory,
}
urlpatterns = patterns('',
# ...
(r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed',
{'feed_dict': feeds}),
# ...
)
Используя новый класс Feed, эти фиды могут быть развернуты непосредственно как представления:
from django.conf.urls.defaults import *
from myproject.feeds import LatestEntries, LatestEntriesByCategory
urlpatterns = patterns('',
# ...
(r'^feeds/latest/$', LatestEntries()),
(r'^feeds/categories/(?P<category_id>\d+)/$', LatestEntriesByCategory()),
# ...
)
Если вы в настоящее время используете представление feed()
, то класс LatestEntries
часто не нужно изменять, кроме подкласса нового класса Feed
. Исключением является случай, когда Django автоматически определяет имя шаблона для отображения элементов description и title фида (если вы не указали атрибуты title_template
и description_template
). Вам следует убедиться, что вы всегда указываете атрибуты title_template
и description_template
или предоставляете методы item_title()
и item_description()
.
Однако LatestEntriesByCategory
использует метод get_object()
с аргументом bits
для указания конкретной категории для показа. В новом классе Feed
метод get_object()
принимает request
и аргументы из URL, поэтому он будет выглядеть следующим образом:
from django.contrib.syndication.views import Feed
from django.shortcuts import get_object_or_404
from myproject.models import Category
class LatestEntriesByCategory(Feed):
def get_object(self, request, category_id):
return get_object_or_404(Category, id=category_id)
# ...
Кроме того, метод get_feed()
на классах Feed
теперь принимает разные аргументы, что может повлиять на вас, если вы используете классы Feed
напрямую. Вместо необязательного аргумента url
, теперь он принимает два аргумента: объект, возвращаемый собственным методом get_object()
, и текущий объект request
.
Чтобы учесть, что классы Feed
не инициализируются для каждого запроса, метод __init__()
теперь по умолчанию не принимает аргументов. Ранее он принимал slug
из URL и объект request
.
В соответствии с RSS best practices, RSS-каналы теперь будут включать элемент atom:link
. Вам может потребоваться обновить свои тесты, чтобы учесть это.
Для получения дополнительной информации смотрите полный syndication framework documentation.
Идентификаторы технических сообщений¶
До версии 1.1 Django использовал идентификаторы технических сообщений, чтобы предоставить локализаторам возможность переводить форматы даты и времени. Это были переводимые translation strings, которые можно было распознать, поскольку все они были в верхнем регистре (например, DATETIME_FORMAT
, DATE_FORMAT
, TIME_FORMAT
). Они были упразднены в пользу новой инфраструктуры Локализация формата, которая позволяет локализаторам указывать эту информацию в formats.py
файле в соответствующей django/conf/locale/<locale name>/
директории.
GeoDjango¶
Чтобы обеспечить поддержку нескольких баз данных, внутренние компоненты базы данных GeoDjango были существенно изменены. Самым большим изменением, несовместимым с обратными изменениями, является то, что модуль django.contrib.gis.db.backend
был переименован в django.contrib.gis.db.backends
, где теперь существует полноценный spatial database backends. В следующих разделах представлена информация о наиболее популярных API, которые были затронуты этими изменениями.
SpatialBackend
¶
До создания отдельных пространственных бэкендов объект django.contrib.gis.db.backend.SpatialBackend
предоставлялся в качестве абстракции для ознакомления с возможностями пространственной базы данных. Все атрибуты и процедуры, предоставляемые SpatialBackend
, теперь являются частью атрибута ops
бэкенда базы данных.
Старый модуль django.contrib.gis.db.backend
все еще предоставляется для обратной совместимости для доступа к объекту SpatialBackend
, который является просто псевдонимом для модуля ops
соединения пространственной базы данных по умолчанию.
Пользователи, которые полагались на недокументированные модули и объекты в django.contrib.gis.db.backend
, а не на абстракции, предоставляемые SpatialBackend
, должны изменить свой код. Например, следующий импорт, который будет работать в версии 1.1 и ниже:
from django.contrib.gis.db.backend.postgis import PostGISAdaptor
Необходимо изменить:
from django.db import connection
PostGISAdaptor = connection.ops.Adapter
SpatialRefSys
и GeometryColumns
модели¶
В предыдущих версиях GeoDjango, django.contrib.gis.db.models
имел модели SpatialRefSys
и GeometryColumns
для запроса таблиц пространственных метаданных OGC spatial_ref_sys
и geometry_columns
, соответственно.
Хотя эти псевдонимы по-прежнему предоставляются, они предназначены только для соединения с базой данных по умолчанию и существуют только в том случае, если соединение по умолчанию использует поддерживаемый бэкенд пространственной базы данных.
Примечание
Поскольку структура таблиц пространственных метаданных OGC отличается в разных пространственных базах данных, модели SpatialRefSys
и GeometryColumns
больше не могут быть связаны с именем приложения gis
. Таким образом, при использовании метода get_models
в следующем примере не будет возвращено ни одной модели:
>>> from django.db.models import get_app, get_models
>>> get_models(get_app('gis'))
[]
Чтобы получить правильные SpatialRefSys
и GeometryColumns
для вашей пространственной базы данных, используйте методы, предоставляемые пространственным бэкендом:
>>> from django.db import connections
>>> SpatialRefSys = connections['my_spatialite'].ops.spatial_ref_sys()
>>> GeometryColumns = connections['my_postgis'].ops.geometry_columns()
Примечание
При использовании моделей, возвращенных методом spatial_ref_sys()
и geometry_columns()
, вам все равно придется использовать правильный псевдоним базы данных при запросе на нестандартном соединении. Другими словами, чтобы убедиться, что модели в приведенном выше примере используют правильную базу данных:
sr_qs = SpatialRefSys.objects.using('my_spatialite').filter(...)
gc_qs = GeometryColumns.objects.using('my_postgis').filter(...)
Код языка no
¶
Используемый в настоящее время код языка для норвежского Bokmål no
заменяется на более распространенный код языка nb
.
Загрузчики шаблонов на основе функций¶
Django 1.2 изменяет механизм загрузки шаблонов, используя подход, основанный на классах. Старые загрузчики шаблонов на основе функций все еще будут работать, но их следует обновить, чтобы использовать новые загрузчики шаблонов на основе классов.