Update 1.2 release notes in anticipation of final release.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@13259 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
James Bennett 2010-05-14 06:51:42 +00:00
parent a193f355a8
commit 23decc4b86
1 changed files with 118 additions and 91 deletions

View File

@ -1,15 +1,18 @@
.. _releases-1.2: .. _releases-1.2:
============================================ ========================
Django 1.2 release notes — UNDER DEVELOPMENT Django 1.2 release notes
============================================ ========================
This page documents release notes for the as-yet-unreleased Django 1.2. As such,
it's tentative and subject to change. It provides up-to-date information for
those who are following trunk.
Django 1.2 includes a number of nifty `new features`_, lots of bug May 14, 2010
fixes and an easy upgrade path from Django 1.1.
Welcome to Django 1.2!
Nearly a year in the making, Django 1.2 packs an impressive list of
`new features`_, and lots of bugfixes. These release notes cover the
new features, as well as important changes you'll want to be aware of
when upgrading from Djagno 1.1 or older versions.
.. _new features: `What's new in Django 1.2`_ .. _new features: `What's new in Django 1.2`_
@ -18,6 +21,19 @@ fixes and an easy upgrade path from Django 1.1.
Backwards-incompatible changes in 1.2 Backwards-incompatible changes in 1.2
===================================== =====================================
There are a number of changes in Django 1.2 which will be
backwards-incompatible; per :ref:`our API stability policy
<misc-api-stability>`, most such changes are being introduced
gradually to allow adequate time to upgrade existing code. For most of
the changes listed below, code written for Django 1.1 or older will
simply raise a ``PendingDeprecationWarning`` in Django 1.2, followed
by a ``DeprecationWarning`` in Django 1.3 before such code finally
stops working entirely in Django 1.4.
Do note, however, that some of the items listed below may require
immediate changes; we encourage you to read these notes carefully to
determine how they'll impact your code.
CSRF Protection CSRF Protection
--------------- ---------------
@ -30,7 +46,7 @@ should be aware of:
should be inserted into forms. should be inserted into forms.
* All contrib apps use a ``csrf_protect`` decorator to protect the view. This * All contrib apps use a ``csrf_protect`` decorator to protect the view. This
requires the use of the csrf_token template tag in the template. If you requires the use of the ``csrf_token`` template tag in the template. If you
have used custom templates for contrib views, you MUST READ THE :ref:`UPGRADE have used custom templates for contrib views, you MUST READ THE :ref:`UPGRADE
INSTRUCTIONS <ref-csrf-upgrading-notes>` to fix those templates. INSTRUCTIONS <ref-csrf-upgrading-notes>` to fix those templates.
@ -39,8 +55,9 @@ should be aware of:
POST requests need to be written to work with the middleware. Instructions POST requests need to be written to work with the middleware. Instructions
on how to do this are found in the CSRF docs. on how to do this are found in the CSRF docs.
* All of the CSRF has moved from contrib to core (with backwards compatible * All of the CSRF has moved from contrib to core (with backwards
imports in the old locations, which are deprecated). compatible imports in the old locations, which are deprecated and
will cease to be supported in Django 1.4).
:ttag:`if` tag changes :ttag:`if` tag changes
---------------------- ----------------------
@ -50,19 +67,21 @@ Due to new features in the :ttag:`if` template tag, it no longer accepts 'and',
cases even though these strings were normally treated as keywords. Now, the cases even though these strings were normally treated as keywords. Now, the
keyword status is always enforced, and template code such as ``{% if not %}`` or keyword status is always enforced, and template code such as ``{% if not %}`` or
``{% if and %}`` will throw a ``TemplateSyntaxError``. Also, ``in`` is a new ``{% if and %}`` will throw a ``TemplateSyntaxError``. Also, ``in`` is a new
keyword and so is not a valid variable name in this context. keyword and so is not a valid variable name in this tag.
``LazyObject`` ``LazyObject``
-------------- --------------
``LazyObject`` is an undocumented utility class used for lazily wrapping other ``LazyObject`` is an undocumented utility class used for lazily
objects of unknown type. In Django 1.1 and earlier, it handled introspection in wrapping other objects of unknown type. In Django 1.1 and earlier, it
a non-standard way, depending on wrapped objects implementing a public method handled introspection in a non-standard way, depending on wrapped
``get_all_members()``. Since this could easily lead to name clashes, it has been objects implementing a public method named
changed to use the standard method, involving ``__members__`` and ``__dir__()``. ``get_all_members()``. Since this could easily lead to name clashes,
If you used ``LazyObject`` in your own code and implemented the it has been changed to use the standard Python introspection method,
``get_all_members()`` method for wrapped objects, you need to make the following involving ``__members__`` and ``__dir__()``. If you used
changes: ``LazyObject`` in your own code and implemented the
``get_all_members()`` method for wrapped objects, you need to make the
following changes:
* If your class does not have special requirements for introspection (i.e., you * If your class does not have special requirements for introspection (i.e., you
have not implemented ``__getattr__()`` or other methods that allow for have not implemented ``__getattr__()`` or other methods that allow for
@ -70,39 +89,41 @@ changes:
``get_all_members()`` method. The default implementation on ``LazyObject`` ``get_all_members()`` method. The default implementation on ``LazyObject``
will do the right thing. will do the right thing.
* If you have more complex requirements for introspection, first rename the * If you have more complex requirements for introspection, first
``get_all_members()`` method to ``__dir__()``. This is the standard method, rename the ``get_all_members()`` method to ``__dir__()``. This is
from Python 2.6 onwards, for supporting introspection. If you require the standard method, from Python 2.6 onwards, for supporting
support for Python < 2.6, add the following code to the class:: introspection. If you require support for Python versions earlier
than 2.6, add the following code to the class::
__members__ = property(lambda self: self.__dir__()) __members__ = property(lambda self: self.__dir__())
.. _specifying-databases: .. _specifying-databases:
Specifying databases Specifying databases
-------------------- --------------------
Prior to Django 1.1, Django used a number of settings to control access to a Prior to Django 1.1, Django used a number of settings to control
single database. Django 1.2 introduces support for multiple databases, and as access to a single database. Django 1.2 introduces support for
a result, the way you define database settings has changed. multiple databases, and as a result the way you define database
settings has changed.
Any existing Django settings file will continue to work as expected until Any existing Django settings file will continue to work as expected
Django 1.4. Until then, old-style database settings will be automatically until Django 1.4. Until then, old-style database settings will be
translated to the new-style format. automatically translated to the new-style format.
In the old-style (pre 1.2) format, you had a number of ``DATABASE_`` settings In the old-style (pre 1.2) format, you had a number of ``DATABASE_``
in your settings file. For example:: settings in your settings file. For example::
DATABASE_NAME = 'test_db' DATABASE_NAME = 'test_db'
DATABASE_ENGINE = 'postgresql_psycopg2' DATABASE_ENGINE = 'postgresql_psycopg2'
DATABASE_USER = 'myusername' DATABASE_USER = 'myusername'
DATABASE_PASSWORD = 's3krit' DATABASE_PASSWORD = 's3krit'
These settings are now in a dictionary named :setting:`DATABASES`. Each item in These settings are now in a dictionary named
the dictionary corresponds to a single database connection, with the name :setting:`DATABASES`. Each item in the dictionary corresponds to a
``'default'`` describing the default database connection. The setting names single database connection, with the name ``'default'`` describing the
have also been shortened. The previous sample settings would now look like this:: default database connection. The setting names have also been
shortened. The previous sample settings would now look like this::
DATABASES = { DATABASES = {
'default': { 'default': {
@ -148,14 +169,14 @@ attributes corresponding to the fields on a model.
In order to support multiple database configurations, Django 1.2 has In order to support multiple database configurations, Django 1.2 has
added a ``_state`` attribute to object instances. This attribute will added a ``_state`` attribute to object instances. This attribute will
appear in ``__dict__`` for a model instance. If your code relies on appear in ``__dict__`` for a model instance. If your code relies on
iterating over __dict__ to obtain a list of fields, you must now iterating over ``__dict__`` to obtain a list of fields, you must now
filter the ``_state`` attribute out of ``__dict__``. be prepared to handle or filter out the ``_state`` attribute.
``get_db_prep_*()`` methods on ``Field`` ``get_db_prep_*()`` methods on ``Field``
---------------------------------------- ----------------------------------------
Prior to 1.2, a custom ``Field`` had the option of defining several Prior to Django 1.2, a custom ``Field`` had the option of defining
functions to support conversion of Python values into several functions to support conversion of Python values into
database-compatible values. A custom field might look something like:: database-compatible values. A custom field might look something like::
class CustomModelField(models.Field): class CustomModelField(models.Field):
@ -209,7 +230,7 @@ We've provided conversion functions that will transparently
convert functions adhering to the old prototype into functions convert functions adhering to the old prototype into functions
compatible with the new prototype. However, these conversion functions compatible with the new prototype. However, these conversion functions
will be removed in Django 1.4, so you should upgrade your ``Field`` will be removed in Django 1.4, so you should upgrade your ``Field``
definitions to use the new prototype now, just to get it over with. definitions to use the new prototype as soon as possible.
If your ``get_db_prep_*()`` methods made no use of the database If your ``get_db_prep_*()`` methods made no use of the database
connection, you should be able to upgrade by renaming connection, you should be able to upgrade by renaming
@ -222,8 +243,8 @@ argument to resolve database-specific values.
Stateful template tags Stateful template tags
---------------------- ----------------------
Template tags that store rendering state on the node itself may experience Template tags that store rendering state on their ``Node`` subclass
problems if they are used with the new :ref:`cached may experience problems if they are used with the new :ref:`cached
template loader<template-loaders>`. template loader<template-loaders>`.
All of the built-in Django template tags are safe to use with the cached All of the built-in Django template tags are safe to use with the cached
@ -247,7 +268,7 @@ with a ``subtemplate.html`` that reads::
{% cycle 'even' 'odd' %} {% cycle 'even' 'odd' %}
Using the non thread-safe, pre-Django 1.2 renderer, this would output:: Using the non-thread-safe, pre-Django 1.2 renderer, this would output::
even odd even odd ... even odd even odd ...
@ -255,11 +276,11 @@ Using the thread-safe Django 1.2 renderer, you will instead get::
even even even even ... even even even even ...
This is because the each rendering of the :ttag:`include` tag is an This is because each rendering of the :ttag:`include` tag is an
independent rendering. When the :ttag:`cycle` tag was not thread safe, independent rendering. When the :ttag:`cycle` tag was not thread safe,
the state of the :ttag:`cycle` tag would leak between multiple renderings the state of the :ttag:`cycle` tag would leak between multiple
of the same :ttag:`include`. Now that the :ttag:`cycle` tag is thread safe, renderings of the same :ttag:`include`. Now that the :ttag:`cycle` tag
this leakage no longer occurs. is thread safe, this leakage no longer occurs.
Test runner exit status code Test runner exit status code
---------------------------- ----------------------------
@ -274,29 +295,32 @@ found at the end of the test runner's output.
Cookie encoding Cookie encoding
--------------- ---------------
To fix bugs with cookies in Internet Explorer, Safari, and possibly other To fix bugs with cookies in Internet Explorer, Safari, and possibly
browsers, our encoding of cookie values was changed so that the characters other browsers, our encoding of cookie values was changed so that the
comma and semi-colon are treated as non-safe characters, and are therefore comma and semicolon are treated as non-safe characters, and are
encoded as ``\054`` and ``\073`` respectively. This could produce backwards therefore encoded as ``\054`` and ``\073`` respectively. This could
incompatibilities, especially if you are storing comma or semi-colon in produce backwards incompatibilities, especially if you are storing
cookies and have javascript code that parses and manipulates cookie values comma or semi-colon in cookies and have javascript code that parses
client-side. and manipulates cookie values client-side.
``user_passes_test``, ``login_required`` and ``permission_required`` ``user_passes_test``, ``login_required`` and ``permission_required``
-------------------------------------------------------------------- --------------------------------------------------------------------
``django.contrib.auth.decorators`` provides the decorators ``login_required``, ``django.contrib.auth.decorators`` provides the decorators
``permission_required`` and ``user_passes_test``. Previously it was possible to ``login_required``, ``permission_required`` and
use these decorators both on functions (where the first argument is 'request') ``user_passes_test``. Previously it was possible to use these
and on methods (where the first argument is 'self', and the second argument is decorators both on functions (where the first argument is 'request')
'request'). However, we have found that the trick which enabled this is and on methods (where the first argument is 'self', and the second
flawed. It only works in limited circumstances, and produces errors that are argument is 'request'). Unfortunately, flaws were discovered in the
very difficult to debug when it does not work. code supporting this: it only works in limited circumstances, and
produces errors that are very difficult to debug when it does not
work.
For this reason, the 'auto adapt' behaviour has been removed, and if you are For this reason, the 'auto adapt' behavior has been removed, and if
using these decorators on methods, you will need to manually apply you are using these decorators on methods, you will need to manually
:func:`django.utils.decorators.method_decorator` to convert the decorator to one apply :func:`django.utils.decorators.method_decorator` to convert the
that works with methods. You would change code from this:: decorator to one that works with methods. For example, you would
change code from this::
class MyClass(object): class MyClass(object):
@ -326,9 +350,10 @@ or::
def my_view(self, request): def my_view(self, request):
pass pass
For those following trunk, this change also applies to other decorators For those of you who've been following the development trunk, this
introduced since 1.1, including ``csrf_protect``, ``cache_control`` and anything change also applies to other decorators introduced since 1.1,
created using ``decorator_from_middleware``. including ``csrf_protect``, ``cache_control`` and anything created
using ``decorator_from_middleware``.
``ModelForm.is_valid()`` and ``ModelForm.errors`` ``ModelForm.is_valid()`` and ``ModelForm.errors``
------------------------------------------------- -------------------------------------------------
@ -340,15 +365,15 @@ cleaned in-place. This conversion used to happen when the model was saved. If
you need an unmodified instance of your model, you should pass a copy to the you need an unmodified instance of your model, you should pass a copy to the
``ModelForm`` constructor. ``ModelForm`` constructor.
``BooleanField`` on MySQL ``BooleanField`` on MySQL
-------------------------- --------------------------
In previous versions of Django ``BoleanFields`` under MySQL would return their In previous versions of Django, a model's ``BooleanField`` under MySQL
values as either ``1`` or ``0``, instead of ``True`` or ``False``. For most would return its value as either ``1`` or ``0``, instead of ``True``
people this shouldn't have been a problem because ``bool`` is a subclass of or ``False``; for most people this wasn't a problem because ``bool``
``int``, however in Django 1.2 MySQL correctly returns a real ``bool``. The is a subclass of ``int`` in Python. In Django 1.2, however,
only time this should ever be an issue is if you were expecting printing the ``BooleanField`` on MySQL correctly returns a real ``bool``. The only
time this should ever be an issue is if you were expecting the
``repr`` of a ``BooleanField`` to print ``1`` or ``0``. ``repr`` of a ``BooleanField`` to print ``1`` or ``0``.
Changes to the interpretation of ``max_num`` in FormSets Changes to the interpretation of ``max_num`` in FormSets
@ -393,26 +418,28 @@ Features deprecated in 1.2
------------------------------- -------------------------------
The ``psycopg1`` library has not been updated since October 2005. As a The ``psycopg1`` library has not been updated since October 2005. As a
result, the ``postgresql`` database backend, which depends on this result, the ``postgresql`` database backend, which uses this library,
library, has been deprecated. has been deprecated.
If you are currently using the ``postgresql`` backend, you should If you are currently using the ``postgresql`` backend, you should
migrate to using the ``postgresql_psycopg2`` backend. To update your migrate to using the ``postgresql_psycopg2`` backend. To update your
code, install the ``psycopg2`` library and change the code, install the ``psycopg2`` library and change the
:setting:`DATABASE_ENGINE` setting to read ``postgresql_psycopg2``. :setting:`DATABASE_ENGINE` setting to use
``django.db.backends.postgresql_psycopg2``.
CSRF response-rewriting middleware CSRF response-rewriting middleware
---------------------------------- ----------------------------------
``CsrfResponseMiddleware``, the middleware that automatically inserted CSRF ``CsrfResponseMiddleware``, the middleware that automatically inserted
tokens into POST forms in outgoing pages, has been deprecated in favor of a CSRF tokens into ``POST`` forms in outgoing pages, has been deprecated
template tag method (see above), and will be removed completely in Django in favor of a template tag method (see above), and will be removed
1.4. ``CsrfMiddleware``, which includes the functionality of completely in Django 1.4. ``CsrfMiddleware``, which includes the
``CsrfResponseMiddleware`` and ``CsrfViewMiddleware``, has likewise been functionality of ``CsrfResponseMiddleware`` and
deprecated. ``CsrfViewMiddleware``, has likewise been deprecated.
Also, the CSRF module has moved from contrib to core, and the old imports are Also, the CSRF module has moved from contrib to core, and the old
deprecated, as described in the :ref:`upgrading notes <ref-csrf-upgrading-notes>`. imports are deprecated, as described in the :ref:`upgrading notes
<ref-csrf-upgrading-notes>`.
``SMTPConnection`` ``SMTPConnection``
------------------ ------------------
@ -720,8 +747,8 @@ replaced by the more common language code ``nb``.
What's new in Django 1.2 What's new in Django 1.2
======================== ========================
CSRF support Improved CSRF protection
------------ ------------------------
Django now has much improved protection against :ref:`Cross-Site Django now has much improved protection against :ref:`Cross-Site
Request Forgery (CSRF) attacks<ref-contrib-csrf>`. This type of attack Request Forgery (CSRF) attacks<ref-contrib-csrf>`. This type of attack
@ -769,8 +796,8 @@ issued at a specific database with the `using()` method on
``QuerySet`` objects. Individual objects can be saved to a specific database ``QuerySet`` objects. Individual objects can be saved to a specific database
by providing a ``using`` argument when you call ``save()``. by providing a ``using`` argument when you call ``save()``.
'Smart' if tag "Smart" :ttag:`if` tag
-------------- ----------------------
The :ttag:`if` tag has been upgraded to be much more powerful. First, we've The :ttag:`if` tag has been upgraded to be much more powerful. First, we've
added support for comparison operators. No longer will you have to type: added support for comparison operators. No longer will you have to type: