mirror of
https://github.com/django/django.git
synced 2024-11-18 15:34:16 +00:00
461 lines
18 KiB
Plaintext
461 lines
18 KiB
Plaintext
========================
|
|
Django 1.1 release notes
|
|
========================
|
|
|
|
July 29, 2009
|
|
|
|
Welcome to Django 1.1!
|
|
|
|
Django 1.1 includes a number of nifty :ref:`new features <whats-new-1.1>`, lots
|
|
of bug fixes, and an easy upgrade path from Django 1.0.
|
|
|
|
.. _backwards-incompatible-changes-1.1:
|
|
|
|
Backwards-incompatible changes in 1.1
|
|
=====================================
|
|
|
|
Django has a policy of :doc:`API stability </misc/api-stability>`. This means
|
|
that, in general, code you develop against Django 1.0 should continue to work
|
|
against 1.1 unchanged. However, we do sometimes make backwards-incompatible
|
|
changes if they're necessary to resolve bugs, and there are a handful of such
|
|
(minor) changes between Django 1.0 and Django 1.1.
|
|
|
|
Before upgrading to Django 1.1 you should double-check that the following
|
|
changes don't impact you, and upgrade your code if they do.
|
|
|
|
Changes to constraint names
|
|
---------------------------
|
|
|
|
Django 1.1 modifies the method used to generate database constraint names so
|
|
that names are consistent regardless of machine word size. This change is
|
|
backwards incompatible for some users.
|
|
|
|
If you are using a 32-bit platform, you're off the hook; you'll observe no
|
|
differences as a result of this change.
|
|
|
|
However, **users on 64-bit platforms may experience some problems** using the
|
|
``reset`` management command. Prior to this change, 64-bit platforms
|
|
would generate a 64-bit, 16 character digest in the constraint name; for
|
|
example::
|
|
|
|
ALTER TABLE myapp_sometable ADD CONSTRAINT object_id_refs_id_5e8f10c132091d1e FOREIGN KEY ...
|
|
|
|
Following this change, all platforms, regardless of word size, will generate a
|
|
32-bit, 8 character digest in the constraint name; for example::
|
|
|
|
ALTER TABLE myapp_sometable ADD CONSTRAINT object_id_refs_id_32091d1e FOREIGN KEY ...
|
|
|
|
As a result of this change, you will not be able to use the ``reset``
|
|
management command on any table made by a 64-bit machine. This is because the
|
|
new generated name will not match the historically generated name; as a
|
|
result, the SQL constructed by the reset command will be invalid.
|
|
|
|
If you need to reset an application that was created with 64-bit constraints,
|
|
you will need to manually drop the old constraint prior to invoking
|
|
``reset``.
|
|
|
|
Test cases are now run in a transaction
|
|
---------------------------------------
|
|
|
|
Django 1.1 runs tests inside a transaction, allowing better test performance
|
|
(see `test performance improvements`_ for details).
|
|
|
|
This change is slightly backwards incompatible if existing tests need to test
|
|
transactional behavior, if they rely on invalid assumptions about the test
|
|
environment, or if they require a specific test case ordering.
|
|
|
|
For these cases, :class:`~django.test.TransactionTestCase` can be used instead.
|
|
This is a just a quick fix to get around test case errors revealed by the new
|
|
rollback approach; in the long-term tests should be rewritten to correct the
|
|
test case.
|
|
|
|
.. _removed-setremoteaddrfromforwardedfor-middleware:
|
|
|
|
Removed ``SetRemoteAddrFromForwardedFor`` middleware
|
|
----------------------------------------------------
|
|
|
|
For convenience, Django 1.0 included an optional middleware class --
|
|
``django.middleware.http.SetRemoteAddrFromForwardedFor`` -- which updated the
|
|
value of ``REMOTE_ADDR`` based on the HTTP ``X-Forwarded-For`` header commonly
|
|
set by some proxy configurations.
|
|
|
|
It has been demonstrated that this mechanism cannot be made reliable enough for
|
|
general-purpose use, and that (despite documentation to the contrary) its
|
|
inclusion in Django may lead application developers to assume that the value of
|
|
``REMOTE_ADDR`` is "safe" or in some way reliable as a source of authentication.
|
|
|
|
While not directly a security issue, we've decided to remove this middleware
|
|
with the Django 1.1 release. It has been replaced with a class that does nothing
|
|
other than raise a ``DeprecationWarning``.
|
|
|
|
If you've been relying on this middleware, the easiest upgrade path is:
|
|
|
|
* Examine `the code as it existed before it was removed`__.
|
|
|
|
* Verify that it works correctly with your upstream proxy, modifying
|
|
it to support your particular proxy (if necessary).
|
|
|
|
* Introduce your modified version of ``SetRemoteAddrFromForwardedFor`` as a
|
|
piece of middleware in your own project.
|
|
|
|
__ https://github.com/django/django/blob/91f18400cc0fb37659e2dbaab5484ff2081f1f30/django/middleware/http.py#L33
|
|
|
|
Names of uploaded files are available later
|
|
-------------------------------------------
|
|
|
|
.. currentmodule:: django.db.models
|
|
|
|
In Django 1.0, files uploaded and stored in a model's :class:`FileField` were
|
|
saved to disk before the model was saved to the database. This meant that the
|
|
actual file name assigned to the file was available before saving. For example,
|
|
it was available in a model's pre-save signal handler.
|
|
|
|
In Django 1.1 the file is saved as part of saving the model in the database, so
|
|
the actual file name used on disk cannot be relied on until *after* the model
|
|
has been saved.
|
|
|
|
Changes to how model formsets are saved
|
|
---------------------------------------
|
|
|
|
In Django 1.1, :class:`~django.forms.models.BaseModelFormSet` now calls
|
|
``ModelForm.save()``.
|
|
|
|
This is backwards-incompatible if you were modifying ``self.initial`` in a model
|
|
formset's ``__init__``, or if you relied on the internal ``_total_form_count``
|
|
or ``_initial_form_count`` attributes of BaseFormSet. Those attributes are now
|
|
public methods.
|
|
|
|
Fixed the ``join`` filter's escaping behavior
|
|
---------------------------------------------
|
|
|
|
The :tfilter:`join` filter no longer escapes the literal value that is
|
|
passed in for the connector.
|
|
|
|
This is backwards incompatible for the special situation of the literal string
|
|
containing one of the five special HTML characters. Thus, if you were writing
|
|
``{{ foo|join:"&" }}``, you now have to write ``{{ foo|join:"&" }}``.
|
|
|
|
The previous behavior was a bug and contrary to what was documented
|
|
and expected.
|
|
|
|
Permanent redirects and the ``redirect_to()`` generic view
|
|
----------------------------------------------------------
|
|
|
|
Django 1.1 adds a ``permanent`` argument to the
|
|
``django.views.generic.simple.redirect_to()`` view. This is technically
|
|
backwards-incompatible if you were using the ``redirect_to`` view with a
|
|
format-string key called 'permanent', which is highly unlikely.
|
|
|
|
.. _deprecated-features-1.1:
|
|
|
|
Features deprecated in 1.1
|
|
==========================
|
|
|
|
One feature has been marked as deprecated in Django 1.1:
|
|
|
|
* You should no longer use ``AdminSite.root()`` to register that admin
|
|
views. That is, if your URLconf contains the line::
|
|
|
|
(r'^admin/(.*)', admin.site.root),
|
|
|
|
You should change it to read::
|
|
|
|
(r'^admin/', include(admin.site.urls)),
|
|
|
|
You should begin to remove use of this feature from your code immediately.
|
|
|
|
``AdminSite.root`` will raise a ``PendingDeprecationWarning`` if used in
|
|
Django 1.1. This warning is hidden by default. In Django 1.2, this warning will
|
|
be upgraded to a ``DeprecationWarning``, which will be displayed loudly. Django
|
|
1.3 will remove ``AdminSite.root()`` entirely.
|
|
|
|
For more details on our deprecation policies and strategy, see
|
|
:doc:`/internals/release-process`.
|
|
|
|
.. _whats-new-1.1:
|
|
|
|
What's new in Django 1.1
|
|
========================
|
|
|
|
Quite a bit: since Django 1.0, we've made 1,290 code commits, fixed 1,206 bugs,
|
|
and added roughly 10,000 lines of documentation.
|
|
|
|
The major new features in Django 1.1 are:
|
|
|
|
ORM improvements
|
|
----------------
|
|
|
|
.. currentmodule:: django.db.models
|
|
|
|
Two major enhancements have been added to Django's object-relational mapper
|
|
(ORM): aggregate support, and query expressions.
|
|
|
|
Aggregate support
|
|
~~~~~~~~~~~~~~~~~
|
|
|
|
It's now possible to run SQL aggregate queries (i.e. ``COUNT()``, ``MAX()``,
|
|
``MIN()``, etc.) from within Django's ORM. You can choose to either return the
|
|
results of the aggregate directly, or else annotate the objects in a
|
|
:class:`~django.db.models.query.QuerySet` with the results of the aggregate
|
|
query.
|
|
|
|
This feature is available as new
|
|
:meth:`~django.db.models.query.QuerySet.aggregate` and
|
|
:meth:`~django.db.models.query.QuerySet.annotate` methods, and is covered in
|
|
detail in :doc:`the ORM aggregation documentation </topics/db/aggregation>`.
|
|
|
|
Query expressions
|
|
~~~~~~~~~~~~~~~~~
|
|
|
|
Queries can now refer to a another field on the query and can traverse
|
|
relationships to refer to fields on related models. This is implemented in the
|
|
new :class:`~django.db.models.F` object; for full details, including examples,
|
|
consult the :class:`F expressions documentation <django.db.models.F>`.
|
|
|
|
Model improvements
|
|
------------------
|
|
|
|
A number of features have been added to Django's model layer:
|
|
|
|
"Unmanaged" models
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
You can now control whether or not Django manages the life-cycle of the database
|
|
tables for a model using the :attr:`~Options.managed` model option. This
|
|
defaults to ``True``, meaning that Django will create the appropriate database
|
|
tables in ``syncdb`` and remove them as part of the ``reset``
|
|
command. That is, Django *manages* the database table's lifecycle.
|
|
|
|
If you set this to ``False``, however, no database table creating or deletion
|
|
will be automatically performed for this model. This is useful if the model
|
|
represents an existing table or a database view that has been created by some
|
|
other means.
|
|
|
|
For more details, see the documentation for the :attr:`~Options.managed`
|
|
option.
|
|
|
|
Proxy models
|
|
~~~~~~~~~~~~
|
|
|
|
You can now create :ref:`proxy models <proxy-models>`: subclasses of existing
|
|
models that only add Python-level (rather than database-level) behavior and
|
|
aren't represented by a new table. That is, the new model is a *proxy* for some
|
|
underlying model, which stores all the real data.
|
|
|
|
All the details can be found in the :ref:`proxy models documentation
|
|
<proxy-models>`. This feature is similar on the surface to unmanaged models,
|
|
so the documentation has an explanation of :ref:`how proxy models differ from
|
|
unmanaged models <proxy-vs-unmanaged-models>`.
|
|
|
|
Deferred fields
|
|
~~~~~~~~~~~~~~~
|
|
|
|
In some complex situations, your models might contain fields which could
|
|
contain a lot of data (for example, large text fields), or require expensive
|
|
processing to convert them to Python objects. If you know you don't need those
|
|
particular fields, you can now tell Django not to retrieve them from the
|
|
database.
|
|
|
|
You'll do this with the new queryset methods
|
|
:meth:`~django.db.models.query.QuerySet.defer` and
|
|
:meth:`~django.db.models.query.QuerySet.only`.
|
|
|
|
Testing improvements
|
|
--------------------
|
|
|
|
A few notable improvements have been made to the :doc:`testing framework
|
|
</topics/testing/index>`.
|
|
|
|
Test performance improvements
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
.. currentmodule:: django.test
|
|
|
|
Tests written using Django's :doc:`testing framework </topics/testing/index>` now run
|
|
dramatically faster (as much as 10 times faster in many cases).
|
|
|
|
This was accomplished through the introduction of transaction-based tests: when
|
|
using :class:`django.test.TestCase`, your tests will now be run in a transaction
|
|
which is rolled back when finished, instead of by flushing and re-populating the
|
|
database. This results in an immense speedup for most types of unit tests. See
|
|
the documentation for :class:`TestCase` and :class:`TransactionTestCase` for a
|
|
full description, and some important notes on database support.
|
|
|
|
Test client improvements
|
|
------------------------
|
|
|
|
A couple of small -- but highly useful -- improvements have been made to the
|
|
test client:
|
|
|
|
* The test :class:`Client` now can automatically follow redirects with the
|
|
``follow`` argument to :meth:`Client.get` and :meth:`Client.post`. This
|
|
makes testing views that issue redirects simpler.
|
|
|
|
* It's now easier to get at the template context in the response returned
|
|
the test client: you'll simply access the context as
|
|
``request.context[key]``. The old way, which treats ``request.context`` as
|
|
a list of contexts, one for each rendered template in the inheritance
|
|
chain, is still available if you need it.
|
|
|
|
New admin features
|
|
------------------
|
|
|
|
Django 1.1 adds a couple of nifty new features to Django's admin interface:
|
|
|
|
Editable fields on the change list
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
You can now make fields editable on the admin list views via the new
|
|
:ref:`list_editable <admin-list-editable>` admin option. These fields will show
|
|
up as form widgets on the list pages, and can be edited and saved in bulk.
|
|
|
|
Admin "actions"
|
|
~~~~~~~~~~~~~~~
|
|
|
|
You can now define :doc:`admin actions </ref/contrib/admin/actions>` that can
|
|
perform some action to a group of models in bulk. Users will be able to select
|
|
objects on the change list page and then apply these bulk actions to all
|
|
selected objects.
|
|
|
|
Django ships with one pre-defined admin action to delete a group of objects in
|
|
one fell swoop.
|
|
|
|
Conditional view processing
|
|
---------------------------
|
|
|
|
Django now has much better support for :doc:`conditional view processing
|
|
</topics/conditional-view-processing>` using the standard ``ETag`` and
|
|
``Last-Modified`` HTTP headers. This means you can now easily short-circuit
|
|
view processing by testing less-expensive conditions. For many views this can
|
|
lead to a serious improvement in speed and reduction in bandwidth.
|
|
|
|
URL namespaces
|
|
--------------
|
|
|
|
Django 1.1 improves :ref:`named URL patterns <naming-url-patterns>` with the
|
|
introduction of URL "namespaces."
|
|
|
|
In short, this feature allows the same group of URLs, from the same application,
|
|
to be included in a Django URLConf multiple times, with varying (and potentially
|
|
nested) named prefixes which will be used when performing reverse resolution. In
|
|
other words, reusable applications like Django's admin interface may be
|
|
registered multiple times without URL conflicts.
|
|
|
|
For full details, see :ref:`the documentation on defining URL namespaces
|
|
<topics-http-defining-url-namespaces>`.
|
|
|
|
GeoDjango
|
|
---------
|
|
|
|
In Django 1.1, GeoDjango_ (i.e. ``django.contrib.gis``) has several new
|
|
features:
|
|
|
|
* Support for SpatiaLite_ -- a spatial database for SQLite -- as a spatial
|
|
backend.
|
|
|
|
* Geographic aggregates (``Collect``, ``Extent``, ``MakeLine``, ``Union``)
|
|
and ``F`` expressions.
|
|
|
|
* New ``GeoQuerySet`` methods: ``collect``, ``geojson``, and
|
|
``snap_to_grid``.
|
|
|
|
* A new list interface methods for ``GEOSGeometry`` objects.
|
|
|
|
For more details, see the GeoDjango documentation.
|
|
|
|
.. _geodjango: http://geodjango.org/
|
|
.. _spatialite: http://www.gaia-gis.it/gaia-sins/
|
|
|
|
Other improvements
|
|
------------------
|
|
|
|
Other new features and changes introduced since Django 1.0 include:
|
|
|
|
* The :doc:`CSRF protection middleware </ref/csrf>` has been split into
|
|
two classes -- ``CsrfViewMiddleware`` checks incoming requests, and
|
|
``CsrfResponseMiddleware`` processes outgoing responses. The combined
|
|
``CsrfMiddleware`` class (which does both) remains for
|
|
backwards-compatibility, but using the split classes is now recommended in
|
|
order to allow fine-grained control of when and where the CSRF processing
|
|
takes place.
|
|
|
|
* ``reverse()`` and code which uses it (e.g., the ``{% url %}`` template tag)
|
|
now works with URLs in Django's administrative site, provided that the admin
|
|
URLs are set up via ``include(admin.site.urls)`` (sending admin requests to
|
|
the ``admin.site.root`` view still works, but URLs in the admin will not be
|
|
"reversible" when configured this way).
|
|
|
|
* The ``include()`` function in Django URLconf modules can now accept sequences
|
|
of URL patterns (generated by ``patterns()``) in addition to module names.
|
|
|
|
* Instances of Django forms (see :doc:`the forms overview </topics/forms/index>`)
|
|
now have two additional methods, ``hidden_fields()`` and ``visible_fields()``,
|
|
which return the list of hidden -- i.e., ``<input type="hidden">`` -- and
|
|
visible fields on the form, respectively.
|
|
|
|
* The ``redirect_to`` generic view
|
|
now accepts an additional keyword argument
|
|
``permanent``. If ``permanent`` is ``True``, the view will emit an HTTP
|
|
permanent redirect (status code 301). If ``False``, the view will emit an HTTP
|
|
temporary redirect (status code 302).
|
|
|
|
* A new database lookup type -- ``week_day`` -- has been added for ``DateField``
|
|
and ``DateTimeField``. This type of lookup accepts a number between 1 (Sunday)
|
|
and 7 (Saturday), and returns objects where the field value matches that day
|
|
of the week. See :ref:`the full list of lookup types <field-lookups>` for
|
|
details.
|
|
|
|
* The ``{% for %}`` tag in Django's template language now accepts an optional
|
|
``{% empty %}`` clause, to be displayed when ``{% for %}`` is asked to loop
|
|
over an empty sequence. See :doc:`the list of built-in template tags
|
|
</ref/templates/builtins>` for examples of this.
|
|
|
|
* The :djadmin:`dumpdata` management command now accepts individual
|
|
model names as arguments, allowing you to export the data just from
|
|
particular models.
|
|
|
|
* There's a new :tfilter:`safeseq` template filter which works just like
|
|
:tfilter:`safe` for lists, marking each item in the list as safe.
|
|
|
|
* :doc:`Cache backends </topics/cache>` now support ``incr()`` and
|
|
``decr()`` commands to increment and decrement the value of a cache key.
|
|
On cache backends that support atomic increment/decrement -- most
|
|
notably, the memcached backend -- these operations will be atomic, and
|
|
quite fast.
|
|
|
|
* Django now can :doc:`easily delegate authentication to the Web server
|
|
</howto/auth-remote-user>` via a new authentication backend that supports
|
|
the standard ``REMOTE_USER`` environment variable used for this purpose.
|
|
|
|
* There's a new :func:`django.shortcuts.redirect` function that makes it
|
|
easier to issue redirects given an object, a view name, or a URL.
|
|
|
|
* The ``postgresql_psycopg2`` backend now supports :ref:`native PostgreSQL
|
|
autocommit <postgresql-notes>`. This is an advanced, PostgreSQL-specific
|
|
feature, that can make certain read-heavy applications a good deal
|
|
faster.
|
|
|
|
What's next?
|
|
============
|
|
|
|
We'll take a short break, and then work on Django 1.2 will begin -- no rest for
|
|
the weary! If you'd like to help, discussion of Django development, including
|
|
progress toward the 1.2 release, takes place daily on the django-developers
|
|
mailing list:
|
|
|
|
* https://groups.google.com/group/django-developers
|
|
|
|
... and in the ``#django-dev`` IRC channel on ``irc.freenode.net``. Feel free to
|
|
join the discussions!
|
|
|
|
Django's online documentation also includes pointers on how to contribute to
|
|
Django:
|
|
|
|
* :doc:`How to contribute to Django </internals/contributing/index>`
|
|
|
|
Contributions on any level -- developing code, writing documentation or simply
|
|
triaging tickets and helping to test proposed bugfixes -- are always welcome and
|
|
appreciated.
|
|
|
|
And that's the way it is.
|