843 lines
35 KiB
Plaintext
843 lines
35 KiB
Plaintext
============================================
|
|
Django 1.3 release notes - UNDER DEVELOPMENT
|
|
============================================
|
|
|
|
This page documents release notes for the as-yet-unreleased Django
|
|
1.3. As such, it's tentative and subject to change. It provides
|
|
up-to-date information for those who are following trunk.
|
|
|
|
Django 1.3 includes a number of nifty `new features`_, lots of bug
|
|
fixes, some minor `backwards incompatible changes`_ and an easy
|
|
upgrade path from Django 1.2.
|
|
|
|
.. _new features: `What's new in Django 1.3`_
|
|
|
|
.. _backwards incompatible changes: backwards-incompatible-changes-1.3_
|
|
|
|
What's new in Django 1.3
|
|
========================
|
|
|
|
Class-based views
|
|
~~~~~~~~~~~~~~~~~
|
|
|
|
Django 1.3 adds a framework that allows you to use a class as a view.
|
|
This means you can compose a view out of a collection of methods that
|
|
can be subclassed and overridden to provide common views of data without
|
|
having to write too much code.
|
|
|
|
Analogs of all the old function-based generic views have been
|
|
provided, along with a completely generic view base class that can be
|
|
used as the basis for reusable applications that can be easily
|
|
extended.
|
|
|
|
See :doc:`the documentation on Class-based Generic Views</topics/class-based-views>`
|
|
for more details. There is also a document to help you :doc:`convert
|
|
your function-based generic views to class-based
|
|
views</topics/generic-views-migration>`.
|
|
|
|
Logging
|
|
~~~~~~~
|
|
|
|
Django 1.3 adds framework-level support for Python's logging module.
|
|
This means you can now easily configure and control logging as part of
|
|
your Django project. A number of logging handlers and logging calls
|
|
have been added to Django's own code as well -- most notably, the
|
|
error emails sent on a HTTP 500 server error are now handled as a
|
|
logging activity. See :doc:`the documentation on Django's logging
|
|
interface </topics/logging>` for more details.
|
|
|
|
Extended static files handling
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Django 1.3 ships with a new contrib app ``'django.contrib.staticfiles'``
|
|
to help developers handle the static media files (images, CSS, Javascript,
|
|
etc.) that are needed to render a complete web page.
|
|
|
|
In previous versions of Django, it was common to place static assets in
|
|
:setting:`MEDIA_ROOT` along with user-uploaded files, and serve them both at
|
|
:setting:`MEDIA_URL`. Part of the purpose of introducing the ``staticfiles``
|
|
app is to make it easier to keep static files separate from user-uploaded
|
|
files. For this reason, you will probably want to make your
|
|
:setting:`MEDIA_ROOT` and :setting:`MEDIA_URL` different from your
|
|
:setting:`STATIC_ROOT` and :setting:`STATIC_URL`. You will need to
|
|
arrange for serving of files in :setting:`MEDIA_ROOT` yourself;
|
|
``staticfiles`` does not deal with user-uploaded media at all.
|
|
|
|
See the :doc:`reference documentation of the app </ref/contrib/staticfiles>`
|
|
for more details or learn how to :doc:`manage static files
|
|
</howto/static-files>`.
|
|
|
|
``unittest2`` support
|
|
~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Python 2.7 introduced some major changes to the unittest library,
|
|
adding some extremely useful features. To ensure that every Django
|
|
project can benefit from these new features, Django ships with a
|
|
copy of unittest2_, a copy of the Python 2.7 unittest library,
|
|
backported for Python 2.4 compatibility.
|
|
|
|
To access this library, Django provides the
|
|
``django.utils.unittest`` module alias. If you are using Python
|
|
2.7, or you have installed unittest2 locally, Django will map the
|
|
alias to the installed version of the unittest library. Otherwise,
|
|
Django will use it's own bundled version of unittest2.
|
|
|
|
To use this alias, simply use::
|
|
|
|
from django.utils import unittest
|
|
|
|
wherever you would have historically used::
|
|
|
|
import unittest
|
|
|
|
If you want to continue to use the base unittest libary, you can --
|
|
you just won't get any of the nice new unittest2 features.
|
|
|
|
.. _unittest2: http://pypi.python.org/pypi/unittest2
|
|
|
|
Transaction context managers
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Users of Python 2.5 and above may now use :ref:`transaction management functions
|
|
<transaction-management-functions>` as `context managers`_. For example::
|
|
|
|
with transaction.autocommit():
|
|
# ...
|
|
|
|
.. _context managers: http://docs.python.org/glossary.html#term-context-manager
|
|
|
|
For more information, see :ref:`transaction-management-functions`.
|
|
|
|
Configurable delete-cascade
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
:class:`~django.db.models.ForeignKey` and
|
|
:class:`~django.db.models.OneToOneField` now accept an
|
|
:attr:`~django.db.models.ForeignKey.on_delete` argument to customize behavior
|
|
when the referenced object is deleted. Previously, deletes were always
|
|
cascaded; available alternatives now include set null, set default, set to any
|
|
value, protect, or do nothing.
|
|
|
|
For more information, see the :attr:`~django.db.models.ForeignKey.on_delete`
|
|
documentation.
|
|
|
|
Contextual markers and comments for translatable strings
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
For translation strings with ambiguous meaning, you can now
|
|
use the ``pgettext`` function to specify the context of the string.
|
|
|
|
And if you just want to add some information for translators, you
|
|
can also add special translator comments in the source.
|
|
|
|
For more information, see :ref:`contextual-markers` and
|
|
:ref:`translator-comments`.
|
|
|
|
TemplateResponse
|
|
~~~~~~~~~~~~~~~~
|
|
|
|
It can sometimes be beneficial to allow decorators or middleware to
|
|
modify a response *after* it has been constructed by the view. For
|
|
example, you may want to change the template that is used, or put
|
|
additional data into the context.
|
|
|
|
However, you can't (easily) modify the content of a basic
|
|
:class:`~django.http.HttpResponse` after it has been constructed. To
|
|
overcome this limitation, Django 1.3 adds a new
|
|
:class:`~django.template.TemplateResponse` class. Unlike basic
|
|
:class:`~django.http.HttpResponse` objects,
|
|
:class:`~django.template.TemplateResponse` objects retain the details
|
|
of the template and context that was provided by the view to compute
|
|
the response. The final output of the response is not computed until
|
|
it is needed, later in the response process.
|
|
|
|
For more details, see the :doc:`documentation </ref/template-response>`
|
|
on the :class:`~django.template.TemplateResponse` class.
|
|
|
|
Caching changes
|
|
~~~~~~~~~~~~~~~
|
|
|
|
Django 1.3 sees the introduction of several improvements to the
|
|
Django's caching infrastructure.
|
|
|
|
Firstly, Django now supports multiple named caches. In the same way
|
|
that Django 1.2 introduced support for multiple database connections,
|
|
Django 1.3 allows you to use the new :setting:`CACHES` setting to
|
|
define multiple named cache connections.
|
|
|
|
Secondly, :ref:`Versioning <cache_versioning>`, :ref:`site-wide
|
|
prefixing <cache_key_prefixing>` and :ref:`transformation
|
|
<cache_key_transformation>` has been added to the cache API.
|
|
|
|
Lastly, support for pylibmc_ has been added to the memcached cache
|
|
backend.
|
|
|
|
For more details, see the :doc:`documentation on
|
|
caching in Django</topics/cache>`.
|
|
|
|
.. _pylibmc: http://sendapatch.se/projects/pylibmc/
|
|
|
|
Permissions for inactive users
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
If you provide a custom auth backend with ``supports_inactive_user`` set to
|
|
``True``, an inactive user model will check the backend for permissions.
|
|
This is useful for further centralizing the permission handling. See the
|
|
:doc:`authentication docs </topics/auth>` for more details.
|
|
|
|
GeoDjango
|
|
~~~~~~~~~
|
|
|
|
The GeoDjango test suite is now included when
|
|
:ref:`running the Django test suite <running-unit-tests>` with ``runtests.py``
|
|
when using :ref:`spatial database backends <spatial-backends>`.
|
|
|
|
``MEDIA_URL`` and ``STATIC_URL`` must end in a slash
|
|
----------------------------------------------------
|
|
|
|
Previously, the ``MEDIA_URL`` setting only required a trailing slash if it
|
|
contained a suffix beyond the domain name.
|
|
|
|
A trailing slash is now *required* for ``MEDIA_URL`` and the new
|
|
``STATIC_URL`` setting as long as it is not blank. This ensures there is
|
|
a consistent way to combine paths in templates.
|
|
|
|
Project settings which provide either of both settings without a trailing
|
|
slash will now raise a ``PendingDeprecation`` warning.
|
|
|
|
In Django 1.4 this same condition will raise an ``ImproperlyConfigured``
|
|
exception.
|
|
|
|
Everything else
|
|
~~~~~~~~~~~~~~~
|
|
|
|
Django :doc:`1.1 <1.1>` and :doc:`1.2 <1.2>` added
|
|
lots of big ticket items to Django, like multiple-database support,
|
|
model validation, and a session-based messages framework. However,
|
|
this focus on big features came at the cost of lots of smaller
|
|
features.
|
|
|
|
To compensate for this, the focus of the Django 1.3 development
|
|
process has been on adding lots of smaller, long standing feature
|
|
requests. These include:
|
|
|
|
* Improved tools for accessing and manipulating the current Site.
|
|
|
|
* A :class:`~django.test.client.RequestFactory` for mocking
|
|
requests in tests.
|
|
|
|
* A new test assertion --
|
|
:meth:`~django.test.client.Client.assertNumQueries` -- making it
|
|
easier to test the database activity associated with a view.
|
|
|
|
* Support for lookups spanning relations in admin's ``list_filter``.
|
|
|
|
* Support for _HTTPOnly cookies.
|
|
|
|
* :meth:`mail_admins()` and :meth:`mail_managers()` now support
|
|
easily attaching HTML content to messages.
|
|
|
|
* :class:`EmailMessage` now supports CC's.
|
|
|
|
* Error emails now include more of the detail and formatting of
|
|
the debug server error page.
|
|
|
|
* :meth:`simple_tag` now accepts a :attr:`takes_context` argument,
|
|
making it easier to write simple template tags that require
|
|
access to template context.
|
|
|
|
* A new :meth:`~django.shortcuts.render()` shortcut -- an
|
|
alternative to :meth:`~django.shortcuts.render_to_response()`
|
|
providing a :class:`~django.template.RequestContext` by
|
|
default.
|
|
|
|
* Support for combining :ref:`F() expressions <query-expressions>`
|
|
with timedelta values when retrieving or updating database values.
|
|
|
|
.. _HTTPOnly: http://www.owasp.org/index.php/HTTPOnly
|
|
|
|
.. _backwards-incompatible-changes-1.3:
|
|
|
|
Backwards-incompatible changes in 1.3
|
|
=====================================
|
|
|
|
CSRF exception for AJAX requests
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Django includes a CSRF-protection mechanism, which makes use of a
|
|
token inserted into outgoing forms. Middleware then checks for the
|
|
token's presence on form submission, and validates it.
|
|
|
|
Prior to Django 1.2.5, our CSRF protection made an exception for AJAX
|
|
requests, on the following basis:
|
|
|
|
* Many AJAX toolkits add an X-Requested-With header when using
|
|
XMLHttpRequest.
|
|
|
|
* Browsers have strict same-origin policies regarding
|
|
XMLHttpRequest.
|
|
|
|
* In the context of a browser, the only way that a custom header
|
|
of this nature can be added is with XMLHttpRequest.
|
|
|
|
Therefore, for ease of use, we did not apply CSRF checks to requests
|
|
that appeared to be AJAX on the basis of the X-Requested-With header.
|
|
The Ruby on Rails web framework had a similar exemption.
|
|
|
|
Recently, engineers at Google made members of the Ruby on Rails
|
|
development team aware of a combination of browser plugins and
|
|
redirects which can allow an attacker to provide custom HTTP headers
|
|
on a request to any website. This can allow a forged request to appear
|
|
to be an AJAX request, thereby defeating CSRF protection which trusts
|
|
the same-origin nature of AJAX requests.
|
|
|
|
Michael Koziarski of the Rails team brought this to our attention, and
|
|
we were able to produce a proof-of-concept demonstrating the same
|
|
vulnerability in Django's CSRF handling.
|
|
|
|
To remedy this, Django will now apply full CSRF validation to all
|
|
requests, regardless of apparent AJAX origin. This is technically
|
|
backwards-incompatible, but the security risks have been judged to
|
|
outweigh the compatibility concerns in this case.
|
|
|
|
Additionally, Django will now accept the CSRF token in the custom HTTP
|
|
header X-CSRFTOKEN, as well as in the form submission itself, for ease
|
|
of use with popular JavaScript toolkits which allow insertion of
|
|
custom headers into all AJAX requests.
|
|
|
|
Please see the :ref:`CSRF docs for example jQuery code <csrf-ajax>`
|
|
that demonstrates this technique, ensuring that you are looking at the
|
|
documentation for your version of Django, as the exact code necessary
|
|
is different for some older versions of Django.
|
|
|
|
Restricted filters in admin interface
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
The Django administrative interface, django.contrib.admin, supports
|
|
filtering of displayed lists of objects by fields on the corresponding
|
|
models, including across database-level relationships. This is
|
|
implemented by passing lookup arguments in the querystring portion of
|
|
the URL, and options on the ModelAdmin class allow developers to
|
|
specify particular fields or relationships which will generate
|
|
automatic links for filtering.
|
|
|
|
One historically-undocumented and -unofficially-supported feature has
|
|
been the ability for a user with sufficient knowledge of a model's
|
|
structure and the format of these lookup arguments to invent useful
|
|
new filters on the fly by manipulating the querystring.
|
|
|
|
However, it has been demonstrated that this can be abused to gain
|
|
access to information outside of an admin user's permissions; for
|
|
example, an attacker with access to the admin and sufficient knowledge
|
|
of model structure and relations could construct query strings which --
|
|
with repeated use of regular-expression lookups supported by the
|
|
Django database API -- expose sensitive information such as users'
|
|
password hashes.
|
|
|
|
To remedy this, django.contrib.admin will now validate that
|
|
querystring lookup arguments either specify only fields on the model
|
|
being viewed, or cross relations which have been explicitly
|
|
whitelisted by the application developer using the pre-existing
|
|
mechanism mentioned above. This is backwards-incompatible for any
|
|
users relying on the prior ability to insert arbitrary lookups.
|
|
|
|
FileField no longer deletes files
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
In earlier Django versions, when a model instance containing a
|
|
:class:`~django.db.models.FileField` was deleted,
|
|
:class:`~django.db.models.FileField` took it upon itself to also delete the
|
|
file from the backend storage. This opened the door to several data-loss
|
|
scenarios, including rolled-back transactions and fields on different models
|
|
referencing the same file. In Django 1.3, :class:`~django.db.models.FileField`
|
|
will never delete files from the backend storage. If you need cleanup of
|
|
orphaned files, you'll need to handle it yourself (for instance, with a custom
|
|
management command that can be run manually or scheduled to run periodically
|
|
via e.g. cron).
|
|
|
|
PasswordInput default rendering behavior
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
The :class:`~django.forms.PasswordInput` form widget, intended for use
|
|
with form fields which represent passwords, accepts a boolean keyword
|
|
argument ``render_value`` indicating whether to send its data back to
|
|
the browser when displaying a submitted form with errors. Prior to
|
|
Django 1.3, this argument defaulted to ``True``, meaning that the
|
|
submitted password would be sent back to the browser as part of the
|
|
form. Developers who wished to add a bit of additional security by
|
|
excluding that value from the redisplayed form could instantiate a
|
|
:class:`~django.forms.PasswordInput` passing ``render_value=False`` .
|
|
|
|
Due to the sensitive nature of passwords, however, Django 1.3 takes
|
|
this step automatically; the default value of ``render_value`` is now
|
|
``False``, and developers who want the password value returned to the
|
|
browser on a submission with errors (the previous behavior) must now
|
|
explicitly indicate this. For example::
|
|
|
|
class LoginForm(forms.Form):
|
|
username = forms.CharField(max_length=100)
|
|
password = forms.CharField(widget=forms.PasswordInput(render_value=True))
|
|
|
|
Clearable default widget for FileField
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Django 1.3 now includes a ``ClearableFileInput`` form widget in addition to
|
|
``FileInput``. ``ClearableFileInput`` renders with a checkbox to clear the
|
|
field's value (if the field has a value and is not required); ``FileInput``
|
|
provided no means for clearing an existing file from a ``FileField``.
|
|
|
|
``ClearableFileInput`` is now the default widget for a ``FileField``, so
|
|
existing forms including ``FileField`` without assigning a custom widget will
|
|
need to account for the possible extra checkbox in the rendered form output.
|
|
|
|
To return to the previous rendering (without the ability to clear the
|
|
``FileField``), use the ``FileInput`` widget in place of
|
|
``ClearableFileInput``. For instance, in a ``ModelForm`` for a hypothetical
|
|
``Document`` model with a ``FileField`` named ``document``::
|
|
|
|
from django import forms
|
|
from myapp.models import Document
|
|
|
|
class DocumentForm(forms.ModelForm):
|
|
class Meta:
|
|
model = Document
|
|
widgets = {'document': forms.FileInput}
|
|
|
|
New index on database session table
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Prior to Django 1.3, the database table used by the database backend
|
|
for the :doc:`sessions </topics/http/sessions>` app had no index on
|
|
the ``expire_date`` column. As a result, date-based queries on the
|
|
session table -- such as the query that is needed to purge old
|
|
sessions -- would be very slow if there were lots of sessions.
|
|
|
|
If you have an existing project that is using the database session
|
|
backend, you don't have to do anything to accommodate this change.
|
|
However, you may get a significant performance boost if you manually
|
|
add the new index to the session table. The SQL that will add the
|
|
index can be found by running the :djadmin:`sqlindexes` admin
|
|
command::
|
|
|
|
python manage.py sqlindexes sessions
|
|
|
|
No more naughty words
|
|
~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Django has historically provided (and enforced) a list of profanities.
|
|
The :doc:`comments app </ref/contrib/comments/index>` has enforced this
|
|
list of profanities, preventing people from submitting comments that
|
|
contained one of those profanities.
|
|
|
|
Unfortunately, the technique used to implement this profanities list
|
|
was woefully naive, and prone to the `Scunthorpe problem`_. Fixing the
|
|
built in filter to fix this problem would require significant effort,
|
|
and since natural language processing isn't the normal domain of a web
|
|
framework, we have "fixed" the problem by making the list of
|
|
prohibited words an empty list.
|
|
|
|
If you want to restore the old behavior, simply put a
|
|
``PROFANITIES_LIST`` setting in your settings file that includes the
|
|
words that you want to prohibit (see the `commit that implemented this
|
|
change`_ if you want to see the list of words that was historically
|
|
prohibited). However, if avoiding profanities is important to you, you
|
|
would be well advised to seek out a better, less naive approach to the
|
|
problem.
|
|
|
|
.. _Scunthorpe problem: http://en.wikipedia.org/wiki/Scunthorpe_problem
|
|
.. _commit that implemented this change: http://code.djangoproject.com/changeset/13996
|
|
|
|
Localflavor changes
|
|
~~~~~~~~~~~~~~~~~~~
|
|
|
|
Django 1.3 introduces the following backwards-incompatible changes to
|
|
local flavors:
|
|
|
|
* Indonesia (id) -- The province "Nanggroe Aceh Darussalam (NAD)"
|
|
has been removed from the province list in favor of the new
|
|
official designation "Aceh (ACE)".
|
|
|
|
FormSet updates
|
|
~~~~~~~~~~~~~~~
|
|
|
|
In Django 1.3 ``FormSet`` creation behavior is modified slightly. Historically
|
|
the class didn't make a distinction between not being passed data and being
|
|
passed empty dictionary. This was inconsistent with behavior in other parts of
|
|
the framework. Starting with 1.3 if you pass in empty dictionary the
|
|
``FormSet`` will raise a ``ValidationError``.
|
|
|
|
For example with a ``FormSet``::
|
|
|
|
>>> class ArticleForm(Form):
|
|
... title = CharField()
|
|
... pub_date = DateField()
|
|
>>> ArticleFormSet = formset_factory(ArticleForm)
|
|
|
|
the following code will raise a ``ValidationError``::
|
|
|
|
>>> ArticleFormSet({})
|
|
Traceback (most recent call last):
|
|
...
|
|
ValidationError: [u'ManagementForm data is missing or has been tampered with']
|
|
|
|
if you need to instantiate an empty ``FormSet``, don't pass in the data or use
|
|
``None``::
|
|
|
|
>>> formset = ArticleFormSet()
|
|
>>> formset = ArticleFormSet(data=None)
|
|
|
|
Callables in templates
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Previously, a callable in a template would only be called automatically as part
|
|
of the variable resolution process if it was retrieved via attribute
|
|
lookup. This was an inconsistency that could result in confusing and unhelpful
|
|
behaviour::
|
|
|
|
>>> Template("{{ user.get_full_name }}").render(Context({'user': user}))
|
|
u'Joe Bloggs'
|
|
>>> Template("{{ full_name }}").render(Context({'full_name': user.get_full_name}))
|
|
u'<bound method User.get_full_name of <...
|
|
|
|
This has been resolved in Django 1.3 - the result in both cases will be ``u'Joe
|
|
Bloggs'``. Although the previous behaviour was not useful for a template language
|
|
designed for web designers, and was never deliberately supported, it is possible
|
|
that some templates may be broken by this change.
|
|
|
|
Use of custom SQL to load initial data in tests
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Django provides a custom SQL hooks as a way to inject hand-crafted SQL
|
|
into the database synchronization process. One of the possible uses
|
|
for this custom SQL is to insert data into your database. If your
|
|
custom SQL contains ``INSERT`` statements, those insertions will be
|
|
performed every time your database is synchronized. This includes the
|
|
synchronization of any test databases that are created when you run a
|
|
test suite.
|
|
|
|
However, in the process of testing the Django 1.3, it was discovered
|
|
that this feature has never completely worked as advertised. When
|
|
using database backends that don't support transactions, or when using
|
|
a TransactionTestCase, data that has been inserted using custom SQL
|
|
will not be visible during the testing process.
|
|
|
|
Unfortunately, there was no way to rectify this problem without
|
|
introducing a backwards incompatibility. Rather than leave
|
|
SQL-inserted initial data in an uncertain state, Django now enforces
|
|
the policy that data inserted by custom SQL will *not* be visible
|
|
during testing.
|
|
|
|
This change only affects the testing process. You can still use custom
|
|
SQL to load data into your production database as part of the syncdb
|
|
process. If you require data to exist during test conditions, you
|
|
should either insert it using :ref:`test fixtures
|
|
<topics-testing-fixtures>`, or using the ``setUp()`` method of your
|
|
test case.
|
|
|
|
Changed priority of translation loading
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Work has been done to homogeneize, simplify, rationalize and properly document
|
|
the algorithm used by Django at runtime to build translations from the
|
|
differents translations found on disk, namely:
|
|
|
|
For translatable literals found in Python code and templates (``'django'``
|
|
gettext domain):
|
|
|
|
* Priorities of translations included with applications listed in the
|
|
:setting:`INSTALLED_APPS` setting were changed. To provide a behavior
|
|
consistent with other parts of Django that also use such setting (templates,
|
|
etc.) now, when building the translation that will be made available, the
|
|
apps listed first have higher precedence than the ones listed later.
|
|
|
|
* Now it is possible to override the translations shipped with applications by
|
|
using the :setting:`LOCALE_PATHS` setting whose translations have now higher
|
|
precedence than the translations of ``INSTALLED_APPS`` applications.
|
|
The relative priority among the values listed in this setting has also been
|
|
modified so the paths listed first have higher precedence than the
|
|
ones listed later.
|
|
|
|
* The ``locale`` subdirectory of the directory containing the settings, that
|
|
usually coincides with and is know as the *project directory* is being
|
|
deprecated in this release as a source of translations. (the precedence of
|
|
these translations is intermediate between applications and ``LOCALE_PATHS``
|
|
translations). See the `corresponding deprecated features section`_
|
|
of this document.
|
|
|
|
For translatable literals found in Javascript code (``'djangojs'`` gettext
|
|
domain):
|
|
|
|
* Similarly to the ``'django'`` domain translations: Overriding of
|
|
translations shipped with applications by using the :setting:`LOCALE_PATHS`
|
|
setting is now possible for this domain too. These translations have higher
|
|
precedence than the translations of Python packages passed to the
|
|
:ref:`javascript_catalog view <javascript_catalog-view>`. Paths listed first
|
|
have higher precedence than the ones listed later.
|
|
|
|
* Translations under the ``locale`` sbdirectory of the *project directory* have
|
|
never been taken in account for JavaScript translations and remain in the
|
|
same situation considering the deprecation of such location.
|
|
|
|
.. _corresponding deprecated features section: loading_of_translations_from_the_project_directory_
|
|
|
|
Transaction management
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
When using managed transactions -- that is, anything but the default
|
|
autocommit mode -- it is important when a transaction is marked as
|
|
"dirty". Dirty transactions are committed by the
|
|
:func:`~django.db.transaction.commit_on_success` decorator or the
|
|
:class:`~django.middleware.transaction.TransactionMiddleware`, and
|
|
:func:`~django.db.transaction.commit_manually` forces them to be
|
|
closed explicitly; clean transactions "get a pass", which means they
|
|
are usually rolled back at the end of a request when the connection is
|
|
closed.
|
|
|
|
Until Django 1.3, transactions were only marked dirty when Django was
|
|
aware of a modifying operation performed in them; that is, either some
|
|
model was saved, some bulk update or delete was performed, or the user
|
|
explicitly called ``transaction.set_dirty()``. In Django 1.3, a
|
|
transaction is marked dirty when *any* database operation is
|
|
performed.
|
|
|
|
As a result of this change, you no longer need to set a transaction
|
|
dirty explicitly when you execute raw SQL or use a data-modifying
|
|
``SELECT``. However, you *do* need to explicitly close any read-only
|
|
transactions that are being managed using
|
|
:func:`~django.db.transaction.commit_manually`. For example::
|
|
|
|
@transaction.commit_manually
|
|
def my_view(request, name):
|
|
obj = get_object_or_404(MyObject, name__iexact=name)
|
|
return render_to_response('template', {'object':obj})
|
|
|
|
Prior to Django 1.3, this would work without error. However, under
|
|
Django 1.3, this will raise a :class:`TransactionManagementError` because
|
|
the read operation that retrieves the ``MyObject`` instance leaves the
|
|
transaction in a dirty state.
|
|
|
|
.. _deprecated-features-1.3:
|
|
|
|
Features deprecated in 1.3
|
|
==========================
|
|
|
|
Django 1.3 deprecates some features from earlier releases.
|
|
These features are still supported, but will be gradually phased out
|
|
over the next few release cycles.
|
|
|
|
Code taking advantage of any of the features below will raise a
|
|
``PendingDeprecationWarning`` in Django 1.3. This warning will be
|
|
silent by default, but may be turned on using Python's `warnings
|
|
module`_, or by running Python with a ``-Wd`` or `-Wall` flag.
|
|
|
|
.. _warnings module: http://docs.python.org/library/warnings.html
|
|
|
|
In Django 1.4, these warnings will become a ``DeprecationWarning``,
|
|
which is *not* silent. In Django 1.5 support for these features will
|
|
be removed entirely.
|
|
|
|
.. seealso::
|
|
|
|
For more details, see the documentation :doc:`Django's release process
|
|
</internals/release-process>` and our :doc:`deprecation timeline
|
|
</internals/deprecation>`.
|
|
|
|
``mod_python`` support
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
The ``mod_python`` library has not had a release since 2007 or a commit since
|
|
2008. The Apache Foundation board voted to remove ``mod_python`` from the set
|
|
of active projects in its version control repositories, and its lead developer
|
|
has shifted all of his efforts toward the lighter, slimmer, more stable, and
|
|
more flexible ``mod_wsgi`` backend.
|
|
|
|
If you are currently using the ``mod_python`` request handler, you
|
|
should redeploy your Django projects using another request handler.
|
|
:doc:`mod_wsgi </howto/deployment/modwsgi>` is the request handler
|
|
recommended by the Django project, but :doc:`FastCGI
|
|
</howto/deployment/fastcgi>` is also supported. Support for
|
|
``mod_python`` deployment will be removed in Django 1.5.
|
|
|
|
Function-based generic views
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
As a result of the introduction of class-based generic views, the
|
|
function-based generic views provided by Django have been deprecated.
|
|
The following modules and the views they contain have been deprecated:
|
|
|
|
* :mod:`django.views.generic.create_update`
|
|
* :mod:`django.views.generic.date_based`
|
|
* :mod:`django.views.generic.list_detail`
|
|
* :mod:`django.views.generic.simple`
|
|
|
|
Test client response ``template`` attribute
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Django's :ref:`test client <test-client>` returns
|
|
:class:`~django.test.client.Response` objects annotated with extra testing
|
|
information. In Django versions prior to 1.3, this included a
|
|
:attr:`~django.test.client.Response.template` attribute containing information
|
|
about templates rendered in generating the response: either None, a single
|
|
:class:`~django.template.Template` object, or a list of
|
|
:class:`~django.template.Template` objects. This inconsistency in return values
|
|
(sometimes a list, sometimes not) made the attribute difficult to work with.
|
|
|
|
In Django 1.3 the :attr:`~django.test.client.Response.template` attribute is
|
|
deprecated in favor of a new :attr:`~django.test.client.Response.templates`
|
|
attribute, which is always a list, even if it has only a single element or no
|
|
elements.
|
|
|
|
``DjangoTestRunner``
|
|
~~~~~~~~~~~~~~~~~~~~
|
|
|
|
As a result of the introduction of support for unittest2, the features
|
|
of :class:`django.test.simple.DjangoTestRunner` (including fail-fast
|
|
and Ctrl-C test termination) have been made redundant. In view of this
|
|
redundancy, :class:`~django.test.simple.DjangoTestRunner` has been
|
|
turned into an empty placeholder class, and will be removed entirely
|
|
in Django 1.5.
|
|
|
|
Changes to :ttag:`url` and :ttag:`ssi`
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Most template tags will allow you to pass in either constants or
|
|
variables as arguments -- for example::
|
|
|
|
{% extends "base.html" %}
|
|
|
|
allows you to specify a base template as a constant, but if you have a
|
|
context variable ``templ`` that contains the value ``base.html``::
|
|
|
|
{% extends templ %}
|
|
|
|
is also legal.
|
|
|
|
However, due to an accident of history, the :ttag:`url` and
|
|
:ttag:`ssi` are different. These tags use the second, quoteless
|
|
syntax, but interpret the argument as a constant. This means it isn't
|
|
possible to use a context variable as the target of a :ttag:`url` and
|
|
:ttag:`ssi` tag.
|
|
|
|
Django 1.3 marks the start of the process to correct this historical
|
|
accident. Django 1.3 adds a new template library -- ``future`` -- that
|
|
provides alternate implementations of the :ttag:`url` and :ttag:`ssi`
|
|
template tags. This ``future`` library implement behavior that makes
|
|
the handling of the first argument consistent with the handling of all
|
|
other variables. So, an existing template that contains::
|
|
|
|
{% url sample %}
|
|
|
|
should be replaced with::
|
|
|
|
{% load url from future %}
|
|
{% url 'sample' %}
|
|
|
|
The tags implementing the old behavior have been deprecated, and in
|
|
Django 1.5, the old behavior will be replaced with the new behavior.
|
|
To ensure compatibility with future versions of Django, existing
|
|
templates should be modified to use the new ``future`` libraries and
|
|
syntax.
|
|
|
|
Changes to the login methods of the admin
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
In previous version the admin app defined login methods in multiple locations
|
|
and ignored the almost identical implementation in the already used auth app.
|
|
A side effect of this duplication was the missing adoption of the changes made
|
|
in r12634_ to support a broader set of characters for usernames.
|
|
|
|
This release refactores the admin's login mechanism to use a subclass of the
|
|
:class:`~django.contrib.auth.forms.AuthenticationForm` instead of a manual
|
|
form validation. The previously undocumented method
|
|
``'django.contrib.admin.sites.AdminSite.display_login_form'`` has been removed
|
|
in favor of a new :attr:`~django.contrib.admin.AdminSite.login_form`
|
|
attribute.
|
|
|
|
.. _r12634: http://code.djangoproject.com/changeset/12634
|
|
|
|
``reset`` and ``sqlreset`` management commands
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Those commands have been deprecated. The ``flush`` and ``sqlflush`` commands
|
|
can be used to delete everything. You can also use ALTER TABLE or DROP TABLE
|
|
statements manually.
|
|
|
|
|
|
GeoDjango
|
|
~~~~~~~~~
|
|
|
|
* The function-based :setting:`TEST_RUNNER` previously used to execute
|
|
the GeoDjango test suite, :func:`django.contrib.gis.tests.run_gis_tests`,
|
|
was deprecated for the class-bassed runner,
|
|
:class:`django.contrib.gis.tests.GeoDjangoTestSuiteRunner`.
|
|
|
|
* Previously, calling :meth:`~django.contrib.gis.geos.GEOSGeometry.transform`
|
|
would silently do nothing when GDAL wasn't available. Now,
|
|
a :class:`~django.contrib.gis.geos.GEOSException` is properly raised
|
|
to indicate possible faulty application code. A warning is now raised
|
|
if :meth:`~django.contrib.gis.geos.GEOSGeometry.transform` is called when
|
|
the SRID of the geometry is less than 0 or ``None``.
|
|
|
|
``CZBirthNumberField.clean``
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Previously this field's ``clean()`` method accepted a second, gender, argument
|
|
which allowed stronger validation checks to be made, however since this
|
|
argument could never actually be passed from the Django form machinery it is
|
|
now pending deprecation.
|
|
|
|
``CompatCookie``
|
|
~~~~~~~~~~~~~~~~
|
|
|
|
Previously, ``django.http`` exposed an undocumented ``CompatCookie`` class,
|
|
which was a bug-fix wrapper around the standard library ``SimpleCookie``. As the
|
|
fixes are moving upstream, this is now deprecated - you should use ``from
|
|
django.http import SimpleCookie`` instead.
|
|
|
|
.. _loading_of_translations_from_the_project_directory:
|
|
|
|
Loading of translations from the project directory
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
This release of Django starts the deprecation process for inclusion of
|
|
translations located under the *project path* in the translation building
|
|
process performed at runtime. The :setting:`LOCALE_PATHS` setting can be used
|
|
for the same task by including in it the filesystem path to the ``locale``
|
|
directory containing project-level translations.
|
|
|
|
Rationale for this decision:
|
|
|
|
* The *project path* has always been a loosely defined concept (actually, the
|
|
directory used for locating project-level translations is the directory
|
|
containing the settings module) and there has been a shift in other parts
|
|
of the framework to stop using it as a reference for location of assets at
|
|
runtime.
|
|
|
|
* Detection of the ``locale`` subdirectory tends to fail when the deployment
|
|
scenario is more complex than the basic one. e.g. it fails when the settings
|
|
module is a directory (ticket #10765).
|
|
|
|
* Potential for strange development- and deployment-time problems like the
|
|
fact that the ``project_dir/locale/`` subdir can generate spurious error
|
|
messages when the project directory is included in the Python path (default
|
|
behavior of ``manage.py runserver``) and then it clashes with the equally
|
|
named standard library module, this is a typical warming message::
|
|
|
|
/usr/lib/python2.6/gettext.py:49: ImportWarning: Not importing directory '/path/to/project/dir/locale': missing __init__.py.
|
|
import locale, copy, os, re, struct, sys
|
|
|
|
* This location wasn't included in the translation building process for
|
|
JavaScript literals.
|
|
|
|
``PermWrapper`` moved to ``django.contrib.auth.context_processors``
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
In Django 1.2, we began the process of changing the location of the
|
|
``auth`` context processor from ``django.core.context_processors`` to
|
|
``django.contrib.auth.context_processors``. However, the
|
|
``PermWrapper`` support class was mistakenly omitted from that
|
|
migration. In Django 1.3, the ``PermWrapper`` class has also been
|
|
moved to ``django.contrib.auth.context_processors``, along with the
|
|
``PermLookupDict`` support class. The new classes are functionally
|
|
identical to their old versions; only the module location has changed.
|