2014-09-03 04:17:46 +08:00
|
|
|
|
========================
|
|
|
|
|
Django 1.7 release notes
|
|
|
|
|
========================
|
|
|
|
|
|
|
|
|
|
*September 2, 2014*
|
2013-07-01 19:53:06 +08:00
|
|
|
|
|
|
|
|
|
Welcome to Django 1.7!
|
|
|
|
|
|
|
|
|
|
These release notes cover the `new features`_, as well as some `backwards
|
|
|
|
|
incompatible changes`_ you'll want to be aware of when upgrading from Django
|
2014-11-05 22:09:25 +08:00
|
|
|
|
1.6 or older versions. We've `begun the deprecation process for some features`_,
|
|
|
|
|
and some features have reached the end of their deprecation process and
|
|
|
|
|
`have been removed`_.
|
2013-07-01 19:53:06 +08:00
|
|
|
|
|
|
|
|
|
.. _`new features`: `What's new in Django 1.7`_
|
|
|
|
|
.. _`backwards incompatible changes`: `Backwards incompatible changes in 1.7`_
|
|
|
|
|
.. _`begun the deprecation process for some features`: `Features deprecated in 1.7`_
|
2014-08-07 12:13:22 +08:00
|
|
|
|
.. _`have been removed`: `Features removed in 1.7`_
|
2013-07-01 19:53:06 +08:00
|
|
|
|
|
2013-07-14 01:29:11 +08:00
|
|
|
|
Python compatibility
|
|
|
|
|
====================
|
|
|
|
|
|
2015-10-05 21:16:53 +08:00
|
|
|
|
Django 1.7 requires Python 2.7, 3.2, 3.3, or 3.4. We **highly recommend** and
|
|
|
|
|
only officially support the latest release of each series.
|
|
|
|
|
|
|
|
|
|
Since Django 1.6, support for Python 2.6 has been dropped and support for
|
|
|
|
|
Python 3.4 has been added.
|
2013-07-14 01:29:11 +08:00
|
|
|
|
|
|
|
|
|
This change should affect only a small number of Django users, as most
|
|
|
|
|
operating-system vendors today are shipping Python 2.7 or newer as their default
|
|
|
|
|
version. If you're still using Python 2.6, however, you'll need to stick to
|
|
|
|
|
Django 1.6 until you can upgrade your Python version. Per :doc:`our support
|
|
|
|
|
policy </internals/release-process>`, Django 1.6 will continue to receive
|
|
|
|
|
security support until the release of Django 1.8.
|
|
|
|
|
|
2013-07-01 19:53:06 +08:00
|
|
|
|
What's new in Django 1.7
|
|
|
|
|
========================
|
|
|
|
|
|
2013-07-30 18:52:36 +08:00
|
|
|
|
Schema migrations
|
|
|
|
|
~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
2013-08-11 03:00:12 +08:00
|
|
|
|
Django now has built-in support for schema migrations. It allows models
|
|
|
|
|
to be updated, changed, and deleted by creating migration files that represent
|
|
|
|
|
the model changes and which can be run on any development, staging or production
|
|
|
|
|
database.
|
2013-07-30 18:52:36 +08:00
|
|
|
|
|
|
|
|
|
Migrations are covered in :doc:`their own documentation</topics/migrations>`,
|
|
|
|
|
but a few of the key features are:
|
|
|
|
|
|
2013-08-27 21:39:56 +08:00
|
|
|
|
* ``syncdb`` has been deprecated and replaced by ``migrate``. Don't worry -
|
2013-08-11 03:00:12 +08:00
|
|
|
|
calls to ``syncdb`` will still work as before.
|
2013-07-30 18:52:36 +08:00
|
|
|
|
|
|
|
|
|
* A new ``makemigrations`` command provides an easy way to autodetect changes
|
|
|
|
|
to your models and make migrations for them.
|
|
|
|
|
|
2014-12-27 00:19:43 +08:00
|
|
|
|
``django.db.models.signals.pre_syncdb`` and
|
|
|
|
|
``django.db.models.signals.post_syncdb`` have been deprecated,
|
2014-09-03 04:17:46 +08:00
|
|
|
|
to be replaced by :data:`~django.db.models.signals.pre_migrate` and
|
|
|
|
|
:data:`~django.db.models.signals.post_migrate` respectively. These
|
|
|
|
|
new signals have slightly different arguments. Check the
|
|
|
|
|
documentation for details.
|
2013-07-30 18:52:36 +08:00
|
|
|
|
|
2013-07-30 19:08:59 +08:00
|
|
|
|
* The ``allow_syncdb`` method on database routers is now called ``allow_migrate``,
|
|
|
|
|
but still performs the same function. Routers with ``allow_syncdb`` methods
|
|
|
|
|
will still work, but that method name is deprecated and you should change
|
|
|
|
|
it as soon as possible (nothing more than renaming is required).
|
2013-07-30 18:52:36 +08:00
|
|
|
|
|
2014-02-09 20:22:29 +08:00
|
|
|
|
* ``initial_data`` fixtures are no longer loaded for apps with migrations; if
|
2014-09-21 23:46:01 +08:00
|
|
|
|
you want to load initial data for an app, we suggest you create a migration for
|
|
|
|
|
your application and define a :class:`~django.db.migrations.operations.RunPython`
|
|
|
|
|
or :class:`~django.db.migrations.operations.RunSQL` operation in the ``operations`` section of the migration.
|
2014-02-09 20:22:29 +08:00
|
|
|
|
|
2014-06-10 00:09:16 +08:00
|
|
|
|
* Test rollback behavior is different for apps with migrations; in particular,
|
2014-06-09 10:30:15 +08:00
|
|
|
|
Django will no longer emulate rollbacks on non-transactional databases or
|
2014-06-10 00:09:16 +08:00
|
|
|
|
inside ``TransactionTestCase`` :ref:`unless specifically requested
|
|
|
|
|
<test-case-serialized-rollback>`.
|
2014-06-09 10:30:15 +08:00
|
|
|
|
|
2014-06-16 02:46:56 +08:00
|
|
|
|
* It is not advised to have apps without migrations depend on (have a
|
2014-12-27 02:56:08 +08:00
|
|
|
|
:ref:`ForeignKey <ref-foreignkey>` or :ref:`ManyToManyField <ref-manytomany>`
|
|
|
|
|
to) apps with migrations.
|
2014-07-11 01:00:09 +08:00
|
|
|
|
|
2014-04-20 20:58:29 +08:00
|
|
|
|
.. _app-loading-refactor-17-release-note:
|
|
|
|
|
|
2013-12-25 02:00:29 +08:00
|
|
|
|
App-loading refactor
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Historically, Django applications were tightly linked to models. A singleton
|
|
|
|
|
known as the "app cache" dealt with both installed applications and models.
|
|
|
|
|
The models module was used as an identifier for applications in many APIs.
|
|
|
|
|
|
|
|
|
|
As the concept of :doc:`Django applications </ref/applications>` matured, this
|
2013-12-25 06:48:22 +08:00
|
|
|
|
code showed some shortcomings. It has been refactored into an "app registry"
|
|
|
|
|
where models modules no longer have a central role and where it's possible to
|
2013-12-25 02:00:29 +08:00
|
|
|
|
attach configuration data to applications.
|
|
|
|
|
|
2013-12-25 06:48:22 +08:00
|
|
|
|
Improvements thus far include:
|
2013-12-25 02:00:29 +08:00
|
|
|
|
|
2013-12-31 07:08:55 +08:00
|
|
|
|
* Applications can run code at startup, before Django does anything else, with
|
2014-01-01 00:55:12 +08:00
|
|
|
|
the :meth:`~django.apps.AppConfig.ready` method of their configuration.
|
2013-12-31 07:08:55 +08:00
|
|
|
|
|
2014-01-06 04:10:15 +08:00
|
|
|
|
* Application labels are assigned correctly to models even when they're
|
|
|
|
|
defined outside of ``models.py``. You don't have to set
|
|
|
|
|
:attr:`~django.db.models.Options.app_label` explicitly any more.
|
|
|
|
|
|
2013-12-25 02:00:29 +08:00
|
|
|
|
* It is possible to omit ``models.py`` entirely if an application doesn't
|
|
|
|
|
have any models.
|
|
|
|
|
|
2013-12-31 23:23:42 +08:00
|
|
|
|
* Applications can be relabeled with the :attr:`~django.apps.AppConfig.label`
|
|
|
|
|
attribute of application configurations, to work around label conflicts.
|
|
|
|
|
|
2013-12-25 02:00:29 +08:00
|
|
|
|
* The name of applications can be customized in the admin with the
|
|
|
|
|
:attr:`~django.apps.AppConfig.verbose_name` of application configurations.
|
|
|
|
|
|
2014-01-25 05:43:00 +08:00
|
|
|
|
* The admin automatically calls :func:`~django.contrib.admin.autodiscover()`
|
|
|
|
|
when Django starts. You can consequently remove this line from your
|
|
|
|
|
URLconf.
|
|
|
|
|
|
2013-12-31 07:08:55 +08:00
|
|
|
|
* Django imports all application configurations and models as soon as it
|
|
|
|
|
starts, through a deterministic and straightforward process. This should
|
|
|
|
|
make it easier to diagnose import issues such as import loops.
|
|
|
|
|
|
2013-08-09 21:31:24 +08:00
|
|
|
|
New method on Field subclasses
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
2014-09-03 04:17:46 +08:00
|
|
|
|
To help power both schema migrations and to enable easier addition of
|
|
|
|
|
composite keys in future releases of Django, the
|
|
|
|
|
:class:`~django.db.models.Field` API now has a new required method:
|
|
|
|
|
``deconstruct()``.
|
2013-08-09 21:31:24 +08:00
|
|
|
|
|
|
|
|
|
This method takes no arguments, and returns a tuple of four items:
|
|
|
|
|
|
|
|
|
|
* ``name``: The field's attribute name on its parent model, or None if it is not part of a model
|
|
|
|
|
* ``path``: A dotted, Python path to the class of this field, including the class name.
|
|
|
|
|
* ``args``: Positional arguments, as a list
|
|
|
|
|
* ``kwargs``: Keyword arguments, as a dict
|
|
|
|
|
|
|
|
|
|
These four values allow any field to be serialized into a file, as well as
|
|
|
|
|
allowing the field to be copied safely, both essential parts of these new features.
|
|
|
|
|
|
|
|
|
|
This change should not affect you unless you write custom Field subclasses;
|
|
|
|
|
if you do, you may need to reimplement the ``deconstruct()`` method if your
|
|
|
|
|
subclass changes the method signature of ``__init__`` in any way. If your
|
|
|
|
|
field just inherits from a built-in Django field and doesn't override ``__init__``,
|
|
|
|
|
no changes are necessary.
|
|
|
|
|
|
|
|
|
|
If you do need to override ``deconstruct()``, a good place to start is the
|
|
|
|
|
built-in Django fields (``django/db/models/fields/__init__.py``) as several
|
|
|
|
|
fields, including ``DecimalField`` and ``DateField``, override it and show how
|
|
|
|
|
to call the method on the superclass and simply add or remove extra arguments.
|
|
|
|
|
|
2014-05-07 14:06:41 +08:00
|
|
|
|
This also means that all arguments to fields must themselves be serializable;
|
|
|
|
|
to see what we consider serializable, and to find out how to make your own
|
|
|
|
|
classes serializable, read the
|
|
|
|
|
:ref:`migration serialization documentation <migration-serializing>`.
|
|
|
|
|
|
2013-07-26 16:59:40 +08:00
|
|
|
|
Calling custom ``QuerySet`` methods from the ``Manager``
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
2014-02-06 03:27:01 +08:00
|
|
|
|
Historically, the recommended way to make reusable model queries was to create
|
|
|
|
|
methods on a custom ``Manager`` class. The problem with this approach was that
|
|
|
|
|
after the first method call, you'd get back a ``QuerySet`` instance and
|
|
|
|
|
couldn't call additional custom manager methods.
|
|
|
|
|
|
|
|
|
|
Though not documented, it was common to work around this issue by creating a
|
|
|
|
|
custom ``QuerySet`` so that custom methods could be chained; but the solution
|
|
|
|
|
had a number of drawbacks:
|
|
|
|
|
|
|
|
|
|
* The custom ``QuerySet`` and its custom methods were lost after the first
|
|
|
|
|
call to ``values()`` or ``values_list()``.
|
|
|
|
|
|
|
|
|
|
* Writing a custom ``Manager`` was still necessary to return the custom
|
|
|
|
|
``QuerySet`` class and all methods that were desired on the ``Manager``
|
|
|
|
|
had to be proxied to the ``QuerySet``. The whole process went against
|
|
|
|
|
the DRY principle.
|
|
|
|
|
|
2013-07-26 16:59:40 +08:00
|
|
|
|
The :meth:`QuerySet.as_manager() <django.db.models.query.QuerySet.as_manager>`
|
2014-02-06 03:27:01 +08:00
|
|
|
|
class method can now directly :ref:`create Manager with QuerySet methods
|
|
|
|
|
<create-manager-with-queryset-methods>`::
|
|
|
|
|
|
|
|
|
|
class FoodQuerySet(models.QuerySet):
|
|
|
|
|
def pizzas(self):
|
|
|
|
|
return self.filter(kind='pizza')
|
|
|
|
|
|
|
|
|
|
def vegetarian(self):
|
|
|
|
|
return self.filter(vegetarian=True)
|
|
|
|
|
|
|
|
|
|
class Food(models.Model):
|
|
|
|
|
kind = models.CharField(max_length=50)
|
2014-08-14 00:33:06 +08:00
|
|
|
|
vegetarian = models.BooleanField(default=False)
|
2014-02-06 03:27:01 +08:00
|
|
|
|
objects = FoodQuerySet.as_manager()
|
|
|
|
|
|
|
|
|
|
Food.objects.pizzas().vegetarian()
|
2013-07-26 16:59:40 +08:00
|
|
|
|
|
2013-09-19 01:31:07 +08:00
|
|
|
|
Using a custom manager when traversing reverse relations
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
It is now possible to :ref:`specify a custom manager
|
2014-02-19 00:49:13 +08:00
|
|
|
|
<using-custom-reverse-manager>` when traversing a reverse relationship::
|
|
|
|
|
|
|
|
|
|
class Blog(models.Model):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
class Entry(models.Model):
|
|
|
|
|
blog = models.ForeignKey(Blog)
|
|
|
|
|
|
|
|
|
|
objects = models.Manager() # Default Manager
|
|
|
|
|
entries = EntryManager() # Custom Manager
|
|
|
|
|
|
|
|
|
|
b = Blog.objects.get(id=1)
|
|
|
|
|
b.entry_set(manager='entries').all()
|
2013-09-19 01:31:07 +08:00
|
|
|
|
|
2014-01-20 10:45:21 +08:00
|
|
|
|
New system check framework
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
We've added a new :doc:`System check framework </ref/checks>` for
|
|
|
|
|
detecting common problems (like invalid models) and providing hints for
|
|
|
|
|
resolving those problems. The framework is extensible so you can add your
|
|
|
|
|
own checks for your own apps and libraries.
|
|
|
|
|
|
|
|
|
|
To perform system checks, you use the :djadmin:`check` management command.
|
2015-01-18 08:00:12 +08:00
|
|
|
|
This command replaces the older ``validate`` management command.
|
2014-01-20 10:45:21 +08:00
|
|
|
|
|
2013-11-07 01:25:05 +08:00
|
|
|
|
New ``Prefetch`` object for advanced ``prefetch_related`` operations.
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
The new :class:`~django.db.models.Prefetch` object allows customizing
|
|
|
|
|
prefetch operations.
|
|
|
|
|
|
|
|
|
|
You can specify the ``QuerySet`` used to traverse a given relation
|
|
|
|
|
or customize the storage location of prefetch results.
|
|
|
|
|
|
|
|
|
|
This enables things like filtering prefetched relations, calling
|
|
|
|
|
:meth:`~django.db.models.query.QuerySet.select_related()` from a prefetched
|
|
|
|
|
relation, or prefetching the same relation multiple times with different
|
|
|
|
|
querysets. See :meth:`~django.db.models.query.QuerySet.prefetch_related()`
|
|
|
|
|
for more details.
|
|
|
|
|
|
2013-07-01 22:48:14 +08:00
|
|
|
|
Admin shortcuts support time zones
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
The "today" and "now" shortcuts next to date and time input widgets in the
|
|
|
|
|
admin are now operating in the :ref:`current time zone
|
|
|
|
|
<default-current-time-zone>`. Previously, they used the browser time zone,
|
|
|
|
|
which could result in saving the wrong value when it didn't match the current
|
|
|
|
|
time zone on the server.
|
|
|
|
|
|
|
|
|
|
In addition, the widgets now display a help message when the browser and
|
|
|
|
|
server time zone are different, to clarify how the value inserted in the field
|
|
|
|
|
will be interpreted.
|
|
|
|
|
|
2013-09-24 08:17:59 +08:00
|
|
|
|
Using database cursors as context managers
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Prior to Python 2.7, database cursors could be used as a context manager. The
|
|
|
|
|
specific backend's cursor defined the behavior of the context manager. The
|
|
|
|
|
behavior of magic method lookups was changed with Python 2.7 and cursors were
|
|
|
|
|
no longer usable as context managers.
|
|
|
|
|
|
2014-09-03 04:17:46 +08:00
|
|
|
|
Django 1.7 allows a cursor to be used as a context manager. That is,
|
|
|
|
|
the following can be used::
|
|
|
|
|
|
|
|
|
|
with connection.cursor() as c:
|
|
|
|
|
c.execute(...)
|
|
|
|
|
|
|
|
|
|
instead of::
|
2013-09-24 08:17:59 +08:00
|
|
|
|
|
|
|
|
|
c = connection.cursor()
|
|
|
|
|
try:
|
|
|
|
|
c.execute(...)
|
|
|
|
|
finally:
|
|
|
|
|
c.close()
|
|
|
|
|
|
2014-01-18 17:09:43 +08:00
|
|
|
|
Custom lookups
|
|
|
|
|
~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
It is now possible to write custom lookups and transforms for the ORM.
|
|
|
|
|
Custom lookups work just like Django's inbuilt lookups (e.g. ``lte``,
|
|
|
|
|
``icontains``) while transforms are a new concept.
|
|
|
|
|
|
|
|
|
|
The :class:`django.db.models.Lookup` class provides a way to add lookup
|
|
|
|
|
operators for model fields. As an example it is possible to add ``day_lte``
|
2014-01-19 04:31:35 +08:00
|
|
|
|
operator for ``DateFields``.
|
2014-01-18 17:09:43 +08:00
|
|
|
|
|
|
|
|
|
The :class:`django.db.models.Transform` class allows transformations of
|
|
|
|
|
database values prior to the final lookup. For example it is possible to
|
|
|
|
|
write a ``year`` transform that extracts year from the field's value.
|
|
|
|
|
Transforms allow for chaining. After the ``year`` transform has been added
|
|
|
|
|
to ``DateField`` it is possible to filter on the transformed value, for
|
|
|
|
|
example ``qs.filter(author__birthdate__year__lte=1981)``.
|
|
|
|
|
|
|
|
|
|
For more information about both custom lookups and transforms refer to
|
2014-09-03 04:17:46 +08:00
|
|
|
|
the :doc:`custom lookups </howto/custom-lookups>` documentation.
|
2014-01-18 17:09:43 +08:00
|
|
|
|
|
2014-07-01 21:48:00 +08:00
|
|
|
|
Improvements to ``Form`` error handling
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
``Form.add_error()``
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
Previously there were two main patterns for handling errors in forms:
|
|
|
|
|
|
|
|
|
|
* Raising a :exc:`~django.core.exceptions.ValidationError` from within certain
|
|
|
|
|
functions (e.g. ``Field.clean()``, ``Form.clean_<fieldname>()``, or
|
|
|
|
|
``Form.clean()`` for non-field errors.)
|
|
|
|
|
|
|
|
|
|
* Fiddling with ``Form._errors`` when targeting a specific field in
|
|
|
|
|
``Form.clean()`` or adding errors from outside of a "clean" method
|
|
|
|
|
(e.g. directly from a view).
|
|
|
|
|
|
|
|
|
|
Using the former pattern was straightforward since the form can guess from the
|
|
|
|
|
context (i.e. which method raised the exception) where the errors belong and
|
|
|
|
|
automatically process them. This remains the canonical way of adding errors
|
|
|
|
|
when possible. However the latter was fiddly and error-prone, since the burden
|
|
|
|
|
of handling edge cases fell on the user.
|
|
|
|
|
|
|
|
|
|
The new :meth:`~django.forms.Form.add_error()` method allows adding errors
|
|
|
|
|
to specific form fields from anywhere without having to worry about the details
|
|
|
|
|
such as creating instances of ``django.forms.utils.ErrorList`` or dealing with
|
|
|
|
|
``Form.cleaned_data``. This new API replaces manipulating ``Form._errors``
|
|
|
|
|
which now becomes a private API.
|
|
|
|
|
|
|
|
|
|
See :ref:`validating-fields-with-clean` for an example using
|
|
|
|
|
``Form.add_error()``.
|
|
|
|
|
|
|
|
|
|
Error metadata
|
|
|
|
|
^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
The :exc:`~django.core.exceptions.ValidationError` constructor accepts metadata
|
|
|
|
|
such as error ``code`` or ``params`` which are then available for interpolating
|
|
|
|
|
into the error message (see :ref:`raising-validation-error` for more details);
|
|
|
|
|
however, before Django 1.7 those metadata were discarded as soon as the errors
|
|
|
|
|
were added to :attr:`Form.errors <django.forms.Form.errors>`.
|
|
|
|
|
|
|
|
|
|
:attr:`Form.errors <django.forms.Form.errors>` and
|
|
|
|
|
``django.forms.utils.ErrorList`` now store the ``ValidationError`` instances
|
|
|
|
|
so these metadata can be retrieved at any time through the new
|
|
|
|
|
:meth:`Form.errors.as_data <django.forms.Form.errors.as_data()>` method.
|
|
|
|
|
|
|
|
|
|
The retrieved ``ValidationError`` instances can then be identified thanks to
|
|
|
|
|
their error ``code`` which enables things like rewriting the error's message
|
|
|
|
|
or writing custom logic in a view when a given error is present. It can also
|
|
|
|
|
be used to serialize the errors in a custom format such as XML.
|
|
|
|
|
|
|
|
|
|
The new :meth:`Form.errors.as_json() <django.forms.Form.errors.as_json()>`
|
|
|
|
|
method is a convenience method which returns error messages along with error
|
|
|
|
|
codes serialized as JSON. ``as_json()`` uses ``as_data()`` and gives an idea
|
|
|
|
|
of how the new system could be extended.
|
|
|
|
|
|
|
|
|
|
Error containers and backward compatibility
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
Heavy changes to the various error containers were necessary in order
|
|
|
|
|
to support the features above, specifically
|
|
|
|
|
:attr:`Form.errors <django.forms.Form.errors>`,
|
|
|
|
|
``django.forms.utils.ErrorList``, and the internal storages of
|
|
|
|
|
:exc:`~django.core.exceptions.ValidationError`. These containers which used
|
|
|
|
|
to store error strings now store ``ValidationError`` instances and public APIs
|
|
|
|
|
have been adapted to make this as transparent as possible, but if you've been
|
|
|
|
|
using private APIs, some of the changes are backwards incompatible; see
|
|
|
|
|
:ref:`validation-error-constructor-and-internal-storage` for more details.
|
|
|
|
|
|
2013-04-20 01:20:23 +08:00
|
|
|
|
Minor features
|
|
|
|
|
~~~~~~~~~~~~~~
|
|
|
|
|
|
2013-08-27 21:39:56 +08:00
|
|
|
|
:mod:`django.contrib.admin`
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
2013-07-18 03:20:20 +08:00
|
|
|
|
|
2013-09-07 04:15:35 +08:00
|
|
|
|
* You can now implement :attr:`~django.contrib.admin.AdminSite.site_header`,
|
|
|
|
|
:attr:`~django.contrib.admin.AdminSite.site_title`, and
|
|
|
|
|
:attr:`~django.contrib.admin.AdminSite.index_title` attributes on a custom
|
|
|
|
|
:class:`~django.contrib.admin.AdminSite` in order to easily change the admin
|
2013-09-07 03:27:40 +08:00
|
|
|
|
site's page title and header text. No more needing to override templates!
|
|
|
|
|
|
2013-02-25 14:18:27 +08:00
|
|
|
|
* Buttons in :mod:`django.contrib.admin` now use the ``border-radius`` CSS
|
|
|
|
|
property for rounded corners rather than GIF background images.
|
|
|
|
|
|
2013-07-28 10:52:59 +08:00
|
|
|
|
* Some admin templates now have ``app-<app_name>`` and ``model-<model_name>``
|
|
|
|
|
classes in their ``<body>`` tag to allow customizing the CSS per app or per
|
|
|
|
|
model.
|
|
|
|
|
|
2013-07-28 10:50:02 +08:00
|
|
|
|
* The admin changelist cells now have a ``field-<field_name>`` class in the
|
|
|
|
|
HTML to enable style customizations.
|
|
|
|
|
|
2013-08-27 21:39:56 +08:00
|
|
|
|
* The admin's search fields can now be customized per-request thanks to the new
|
|
|
|
|
:meth:`django.contrib.admin.ModelAdmin.get_search_fields` method.
|
2013-07-28 23:11:04 +08:00
|
|
|
|
|
2013-08-27 21:39:56 +08:00
|
|
|
|
* The :meth:`ModelAdmin.get_fields()
|
|
|
|
|
<django.contrib.admin.ModelAdmin.get_fields>` method may be overridden to
|
|
|
|
|
customize the value of :attr:`ModelAdmin.fields
|
|
|
|
|
<django.contrib.admin.ModelAdmin.fields>`.
|
|
|
|
|
|
2012-12-18 08:04:10 +08:00
|
|
|
|
* In addition to the existing ``admin.site.register`` syntax, you can use the
|
|
|
|
|
new :func:`~django.contrib.admin.register` decorator to register a
|
|
|
|
|
:class:`~django.contrib.admin.ModelAdmin`.
|
|
|
|
|
|
2013-09-07 02:25:13 +08:00
|
|
|
|
* You may specify :meth:`ModelAdmin.list_display_links
|
|
|
|
|
<django.contrib.admin.ModelAdmin.list_display_links>` ``= None`` to disable
|
|
|
|
|
links on the change list page grid.
|
|
|
|
|
|
2013-10-24 23:28:09 +08:00
|
|
|
|
* You may now specify :attr:`ModelAdmin.view_on_site
|
|
|
|
|
<django.contrib.admin.ModelAdmin.view_on_site>` to control whether or not to
|
|
|
|
|
display the "View on site" link.
|
|
|
|
|
|
2014-01-23 10:13:59 +08:00
|
|
|
|
* You can specify a descending ordering for a :attr:`ModelAdmin.list_display
|
|
|
|
|
<django.contrib.admin.ModelAdmin.list_display>` value by prefixing the
|
|
|
|
|
``admin_order_field`` value with a hyphen.
|
|
|
|
|
|
2014-02-27 06:34:19 +08:00
|
|
|
|
* The :meth:`ModelAdmin.get_changeform_initial_data()
|
|
|
|
|
<django.contrib.admin.ModelAdmin.get_changeform_initial_data>` method may be
|
|
|
|
|
overridden to define custom behavior for setting initial change form data.
|
|
|
|
|
|
2013-08-27 21:39:56 +08:00
|
|
|
|
:mod:`django.contrib.auth`
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
* Any ``**kwargs`` passed to
|
|
|
|
|
:meth:`~django.contrib.auth.models.User.email_user()` are passed to the
|
|
|
|
|
underlying :meth:`~django.core.mail.send_mail()` call.
|
|
|
|
|
|
|
|
|
|
* The :func:`~django.contrib.auth.decorators.permission_required` decorator can
|
|
|
|
|
take a list of permissions as well as a single permission.
|
|
|
|
|
|
|
|
|
|
* You can override the new :meth:`AuthenticationForm.confirm_login_allowed()
|
|
|
|
|
<django.contrib.auth.forms.AuthenticationForm.confirm_login_allowed>` method
|
|
|
|
|
to more easily customize the login policy.
|
|
|
|
|
|
|
|
|
|
* :func:`django.contrib.auth.views.password_reset` takes an optional
|
|
|
|
|
``html_email_template_name`` parameter used to send a multipart HTML email
|
|
|
|
|
for password resets.
|
|
|
|
|
|
2014-04-01 08:16:09 +08:00
|
|
|
|
* The :meth:`AbstractBaseUser.get_session_auth_hash()
|
|
|
|
|
<django.contrib.auth.models.AbstractBaseUser.get_session_auth_hash>`
|
|
|
|
|
method was added and if your :setting:`AUTH_USER_MODEL` inherits from
|
|
|
|
|
:class:`~django.contrib.auth.models.AbstractBaseUser`, changing a user's
|
|
|
|
|
password now invalidates old sessions if the
|
2015-09-03 08:50:34 +08:00
|
|
|
|
``django.contrib.auth.middleware.SessionAuthenticationMiddleware`` is
|
|
|
|
|
enabled. See :ref:`session-invalidation-on-password-change` for more details.
|
2014-04-01 08:16:09 +08:00
|
|
|
|
|
2014-10-18 04:50:24 +08:00
|
|
|
|
``django.contrib.formtools``
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
2014-02-10 00:44:31 +08:00
|
|
|
|
|
|
|
|
|
* Calls to :meth:`WizardView.done()
|
2014-10-18 04:50:24 +08:00
|
|
|
|
<formtools.wizard.views.WizardView.done>` now include a
|
2014-02-10 00:44:31 +08:00
|
|
|
|
``form_dict`` to allow easier access to forms by their step name.
|
|
|
|
|
|
2013-10-13 00:07:24 +08:00
|
|
|
|
:mod:`django.contrib.gis`
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
* The default OpenLayers library version included in widgets has been updated
|
|
|
|
|
from 2.11 to 2.13.
|
|
|
|
|
|
2013-12-24 23:53:09 +08:00
|
|
|
|
* Prepared geometries now also support the ``crosses``, ``disjoint``,
|
|
|
|
|
``overlaps``, ``touches`` and ``within`` predicates, if GEOS 3.3 or later is
|
|
|
|
|
installed.
|
|
|
|
|
|
2013-08-27 21:39:56 +08:00
|
|
|
|
:mod:`django.contrib.messages`
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
* The backends for :mod:`django.contrib.messages` that use cookies, will now
|
|
|
|
|
follow the :setting:`SESSION_COOKIE_SECURE` and
|
|
|
|
|
:setting:`SESSION_COOKIE_HTTPONLY` settings.
|
|
|
|
|
|
2013-10-29 04:52:11 +08:00
|
|
|
|
* The :ref:`messages context processor <message-displaying>` now adds a
|
|
|
|
|
dictionary of default levels under the name ``DEFAULT_MESSAGE_LEVELS``.
|
|
|
|
|
|
2013-11-07 23:50:51 +08:00
|
|
|
|
* :class:`~django.contrib.messages.storage.base.Message` objects now have a
|
|
|
|
|
``level_tag`` attribute that contains the string representation of the
|
|
|
|
|
message level.
|
|
|
|
|
|
2013-05-21 03:22:38 +08:00
|
|
|
|
:mod:`django.contrib.redirects`
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
* :class:`~django.contrib.redirects.middleware.RedirectFallbackMiddleware`
|
|
|
|
|
has two new attributes
|
|
|
|
|
(:attr:`~django.contrib.redirects.middleware.RedirectFallbackMiddleware.response_gone_class`
|
|
|
|
|
and
|
|
|
|
|
:attr:`~django.contrib.redirects.middleware.RedirectFallbackMiddleware.response_redirect_class`)
|
|
|
|
|
that specify the types of :class:`~django.http.HttpResponse` instances the
|
|
|
|
|
middleware returns.
|
|
|
|
|
|
2013-08-30 12:03:23 +08:00
|
|
|
|
:mod:`django.contrib.sessions`
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
* The ``"django.contrib.sessions.backends.cached_db"`` session backend now
|
|
|
|
|
respects :setting:`SESSION_CACHE_ALIAS`. In previous versions, it always used
|
|
|
|
|
the `default` cache.
|
|
|
|
|
|
2013-08-27 21:39:56 +08:00
|
|
|
|
:mod:`django.contrib.sitemaps`
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
2013-02-23 23:28:45 +08:00
|
|
|
|
|
2013-07-23 22:25:21 +08:00
|
|
|
|
* The :mod:`sitemap framework<django.contrib.sitemaps>` now makes use of
|
|
|
|
|
:attr:`~django.contrib.sitemaps.Sitemap.lastmod` to set a ``Last-Modified``
|
|
|
|
|
header in the response. This makes it possible for the
|
|
|
|
|
:class:`~django.middleware.http.ConditionalGetMiddleware` to handle
|
|
|
|
|
conditional ``GET`` requests for sitemaps which set ``lastmod``.
|
|
|
|
|
|
2013-11-19 04:16:09 +08:00
|
|
|
|
:mod:`django.contrib.sites`
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
2014-03-22 00:24:49 +08:00
|
|
|
|
* The new :class:`django.contrib.sites.middleware.CurrentSiteMiddleware` allows
|
2013-11-19 04:16:09 +08:00
|
|
|
|
setting the current site on each request.
|
|
|
|
|
|
2013-10-19 20:40:12 +08:00
|
|
|
|
:mod:`django.contrib.staticfiles`
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
* The :ref:`static files storage classes <staticfiles-storages>` may be
|
2013-11-05 18:02:54 +08:00
|
|
|
|
subclassed to override the permissions that collected static files and
|
|
|
|
|
directories receive by setting the
|
2013-10-19 20:40:12 +08:00
|
|
|
|
:attr:`~django.core.files.storage.FileSystemStorage.file_permissions_mode`
|
2013-11-05 18:02:54 +08:00
|
|
|
|
and :attr:`~django.core.files.storage.FileSystemStorage.directory_permissions_mode`
|
|
|
|
|
parameters. See :djadmin:`collectstatic` for example usage.
|
2013-10-19 20:40:12 +08:00
|
|
|
|
|
2014-01-10 08:31:36 +08:00
|
|
|
|
* The :class:`~django.contrib.staticfiles.storage.CachedStaticFilesStorage`
|
|
|
|
|
backend gets a sibling class called
|
|
|
|
|
:class:`~django.contrib.staticfiles.storage.ManifestStaticFilesStorage`
|
|
|
|
|
that doesn't use the cache system at all but instead a JSON file called
|
|
|
|
|
``staticfiles.json`` for storing the mapping between the original file name
|
|
|
|
|
(e.g. ``css/styles.css``) and the hashed file name (e.g.
|
2014-09-09 22:00:01 +08:00
|
|
|
|
``css/styles.55e7cbb9ba48.css``). The ``staticfiles.json`` file is created
|
2014-01-10 08:31:36 +08:00
|
|
|
|
when running the :djadmin:`collectstatic` management command and should
|
|
|
|
|
be a less expensive alternative for remote storages such as Amazon S3.
|
|
|
|
|
|
|
|
|
|
See the :class:`~django.contrib.staticfiles.storage.ManifestStaticFilesStorage`
|
|
|
|
|
docs for more information.
|
|
|
|
|
|
2014-02-10 04:35:35 +08:00
|
|
|
|
* :djadmin:`findstatic` now accepts verbosity flag level 2, meaning it will
|
|
|
|
|
show the relative paths of the directories it searched. See
|
|
|
|
|
:djadmin:`findstatic` for example output.
|
|
|
|
|
|
2013-08-27 21:39:56 +08:00
|
|
|
|
:mod:`django.contrib.syndication`
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
* The :class:`~django.utils.feedgenerator.Atom1Feed` syndication feed's
|
|
|
|
|
``updated`` element now utilizes ``updateddate`` instead of ``pubdate``,
|
|
|
|
|
allowing the ``published`` element to be included in the feed (which
|
|
|
|
|
relies on ``pubdate``).
|
|
|
|
|
|
2013-10-19 06:49:24 +08:00
|
|
|
|
Cache
|
|
|
|
|
^^^^^
|
|
|
|
|
|
|
|
|
|
* Access to caches configured in :setting:`CACHES` is now available via
|
|
|
|
|
:data:`django.core.cache.caches`. This dict-like object provides a different
|
2014-12-27 00:46:48 +08:00
|
|
|
|
instance per thread. It supersedes ``django.core.cache.get_cache()`` which
|
2013-10-19 06:49:24 +08:00
|
|
|
|
is now deprecated.
|
|
|
|
|
|
2014-03-01 10:03:46 +08:00
|
|
|
|
* If you instantiate cache backends directly, be aware that they aren't
|
2013-10-19 06:49:24 +08:00
|
|
|
|
thread-safe any more, as :data:`django.core.cache.caches` now yields
|
2013-12-15 17:00:13 +08:00
|
|
|
|
different instances per thread.
|
2013-10-19 06:49:24 +08:00
|
|
|
|
|
2014-02-24 06:58:26 +08:00
|
|
|
|
* Defining the :setting:`TIMEOUT <CACHES-TIMEOUT>` argument of the
|
|
|
|
|
:setting:`CACHES` setting as ``None`` will set the cache keys as
|
|
|
|
|
"non-expiring" by default. Previously, it was only possible to pass
|
2014-05-11 10:13:50 +08:00
|
|
|
|
``timeout=None`` to the cache backend's ``set()`` method.
|
2014-02-24 06:58:26 +08:00
|
|
|
|
|
2014-03-04 08:52:28 +08:00
|
|
|
|
Cross Site Request Forgery
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
* The :setting:`CSRF_COOKIE_AGE` setting facilitates the use of session-based
|
|
|
|
|
CSRF cookies.
|
|
|
|
|
|
2013-08-27 21:39:56 +08:00
|
|
|
|
Email
|
|
|
|
|
^^^^^
|
|
|
|
|
|
|
|
|
|
* :func:`~django.core.mail.send_mail` now accepts an ``html_message``
|
|
|
|
|
parameter for sending a multipart ``text/plain`` and ``text/html`` email.
|
2013-10-15 23:18:06 +08:00
|
|
|
|
* The SMTP :class:`~django.core.mail.backends.smtp.EmailBackend` now accepts a
|
2014-09-14 08:20:01 +08:00
|
|
|
|
``timeout`` parameter.
|
2013-08-27 21:39:56 +08:00
|
|
|
|
|
2013-09-18 09:34:45 +08:00
|
|
|
|
File Storage
|
|
|
|
|
^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
* File locking on Windows previously depended on the PyWin32 package; if it
|
|
|
|
|
wasn't installed, file locking failed silently. That dependency has been
|
|
|
|
|
removed, and file locking is now implemented natively on both Windows
|
|
|
|
|
and Unix.
|
|
|
|
|
|
2013-08-27 21:39:56 +08:00
|
|
|
|
File Uploads
|
|
|
|
|
^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
* The new :attr:`UploadedFile.content_type_extra
|
|
|
|
|
<django.core.files.uploadedfile.UploadedFile.content_type_extra>` attribute
|
|
|
|
|
contains extra parameters passed to the ``content-type`` header on a file
|
|
|
|
|
upload.
|
|
|
|
|
|
|
|
|
|
* The new :setting:`FILE_UPLOAD_DIRECTORY_PERMISSIONS` setting controls
|
|
|
|
|
the file system permissions of directories created during file upload, like
|
|
|
|
|
:setting:`FILE_UPLOAD_PERMISSIONS` does for the files themselves.
|
|
|
|
|
|
2013-10-11 20:07:25 +08:00
|
|
|
|
* The :attr:`FileField.upload_to <django.db.models.FileField.upload_to>`
|
|
|
|
|
attribute is now optional. If it is omitted or given ``None`` or an empty
|
|
|
|
|
string, a subdirectory won't be used for storing the uploaded files.
|
|
|
|
|
|
2014-05-26 04:52:47 +08:00
|
|
|
|
* Uploaded files are now explicitly closed before the response is delivered to
|
|
|
|
|
the client. Partially uploaded files are also closed as long as they are
|
|
|
|
|
named ``file`` in the upload handler.
|
|
|
|
|
|
2014-08-08 22:20:08 +08:00
|
|
|
|
* :meth:`Storage.get_available_name()
|
|
|
|
|
<django.core.files.storage.Storage.get_available_name>` now appends an
|
|
|
|
|
underscore plus a random 7 character alphanumeric string (e.g.
|
|
|
|
|
``"_x3a1gho"``), rather than iterating through an underscore followed by a
|
|
|
|
|
number (e.g. ``"_1"``, ``"_2"``, etc.) to prevent a denial-of-service attack.
|
|
|
|
|
This change was also made in the 1.6.6, 1.5.9, and 1.4.14 security releases.
|
|
|
|
|
|
2013-08-27 21:39:56 +08:00
|
|
|
|
Forms
|
|
|
|
|
^^^^^
|
|
|
|
|
|
|
|
|
|
* The ``<label>`` and ``<input>`` tags rendered by
|
|
|
|
|
:class:`~django.forms.RadioSelect` and
|
|
|
|
|
:class:`~django.forms.CheckboxSelectMultiple` when looping over the radio
|
|
|
|
|
buttons or checkboxes now include ``for`` and ``id`` attributes, respectively.
|
|
|
|
|
Each radio button or checkbox includes an ``id_for_label`` attribute to
|
|
|
|
|
output the element's ID.
|
2013-07-30 20:24:13 +08:00
|
|
|
|
|
2014-03-04 22:12:13 +08:00
|
|
|
|
* The ``<textarea>`` tags rendered by :class:`~django.forms.Textarea` now
|
|
|
|
|
include a ``maxlength`` attribute if the :class:`~django.db.models.TextField`
|
|
|
|
|
model field has a ``max_length``.
|
|
|
|
|
|
2013-07-21 05:49:33 +08:00
|
|
|
|
* :attr:`Field.choices<django.db.models.Field.choices>` now allows you to
|
|
|
|
|
customize the "empty choice" label by including a tuple with an empty string
|
|
|
|
|
or ``None`` for the key and the custom label as the value. The default blank
|
|
|
|
|
option ``"----------"`` will be omitted in this case.
|
|
|
|
|
|
2013-05-07 17:06:03 +08:00
|
|
|
|
* :class:`~django.forms.MultiValueField` allows optional subfields by setting
|
|
|
|
|
the ``require_all_fields`` argument to ``False``. The ``required`` attribute
|
|
|
|
|
for each individual field will be respected, and a new ``incomplete``
|
|
|
|
|
validation error will be raised when any required fields are empty.
|
|
|
|
|
|
2013-08-08 21:05:55 +08:00
|
|
|
|
* The :meth:`~django.forms.Form.clean` method on a form no longer needs to
|
|
|
|
|
return ``self.cleaned_data``. If it does return a changed dictionary then
|
2013-08-08 21:27:48 +08:00
|
|
|
|
that will still be used.
|
2013-08-08 21:05:55 +08:00
|
|
|
|
|
2013-11-19 01:24:56 +08:00
|
|
|
|
* After a temporary regression in Django 1.6, it's now possible again to make
|
|
|
|
|
:class:`~django.forms.TypedChoiceField` ``coerce`` method return an arbitrary
|
|
|
|
|
value.
|
|
|
|
|
|
2013-08-28 14:22:47 +08:00
|
|
|
|
* :attr:`SelectDateWidget.months
|
2015-01-26 11:28:57 +08:00
|
|
|
|
<django.forms.SelectDateWidget.months>` can be used to
|
2013-08-28 14:22:47 +08:00
|
|
|
|
customize the wording of the months displayed in the select widget.
|
|
|
|
|
|
2013-05-24 14:02:07 +08:00
|
|
|
|
* The ``min_num`` and ``validate_min`` parameters were added to
|
|
|
|
|
:func:`~django.forms.formsets.formset_factory` to allow validating
|
|
|
|
|
a minimum number of submitted forms.
|
|
|
|
|
|
2013-07-21 03:25:27 +08:00
|
|
|
|
* The metaclasses used by ``Form`` and ``ModelForm`` have been reworked to
|
|
|
|
|
support more inheritance scenarios. The previous limitation that prevented
|
|
|
|
|
inheriting from both ``Form`` and ``ModelForm`` simultaneously have been
|
|
|
|
|
removed as long as ``ModelForm`` appears first in the MRO.
|
|
|
|
|
|
2014-05-24 17:52:18 +08:00
|
|
|
|
* It's now possible to remove a field from a ``Form`` when subclassing by
|
|
|
|
|
setting the name to ``None``.
|
2013-10-14 23:42:33 +08:00
|
|
|
|
|
2014-02-04 02:31:27 +08:00
|
|
|
|
* It's now possible to customize the error messages for ``ModelForm``’s
|
|
|
|
|
``unique``, ``unique_for_date``, and ``unique_together`` constraints.
|
|
|
|
|
In order to support ``unique_together`` or any other ``NON_FIELD_ERROR``,
|
|
|
|
|
``ModelForm`` now looks for the ``NON_FIELD_ERROR`` key in the
|
|
|
|
|
``error_messages`` dictionary of the ``ModelForm``’s inner ``Meta`` class.
|
|
|
|
|
See :ref:`considerations regarding model's error_messages
|
|
|
|
|
<considerations-regarding-model-errormessages>` for more details.
|
|
|
|
|
|
2012-11-17 20:14:12 +08:00
|
|
|
|
Internationalization
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
* The :attr:`django.middleware.locale.LocaleMiddleware.response_redirect_class`
|
|
|
|
|
attribute allows you to customize the redirects issued by the middleware.
|
|
|
|
|
|
2013-10-18 19:56:32 +08:00
|
|
|
|
* The :class:`~django.middleware.locale.LocaleMiddleware` now stores the user's
|
2014-02-22 21:27:57 +08:00
|
|
|
|
selected language with the session key ``_language``. This should only be
|
|
|
|
|
accessed using the :data:`~django.utils.translation.LANGUAGE_SESSION_KEY`
|
|
|
|
|
constant. Previously it was stored with the key ``django_language`` and the
|
|
|
|
|
``LANGUAGE_SESSION_KEY`` constant did not exist, but keys reserved for Django
|
|
|
|
|
should start with an underscore. For backwards compatibility ``django_language``
|
|
|
|
|
is still read from in 1.7. Sessions will be migrated to the new key
|
|
|
|
|
as they are written.
|
2013-10-18 19:56:32 +08:00
|
|
|
|
|
2014-05-11 10:13:50 +08:00
|
|
|
|
* The :ttag:`blocktrans` tag now supports a ``trimmed`` option. This
|
2013-11-03 03:01:17 +08:00
|
|
|
|
option will remove newline characters from the beginning and the end of the
|
|
|
|
|
content of the ``{% blocktrans %}`` tag, replace any whitespace at the
|
|
|
|
|
beginning and end of a line and merge all lines into one using a space
|
|
|
|
|
character to separate them. This is quite useful for indenting the content of
|
|
|
|
|
a ``{% blocktrans %}`` tag without having the indentation characters end up
|
|
|
|
|
in the corresponding entry in the PO file, which makes the translation
|
|
|
|
|
process easier.
|
|
|
|
|
|
2013-11-30 17:53:08 +08:00
|
|
|
|
* When you run :djadmin:`makemessages` from the root directory of your project,
|
|
|
|
|
any extracted strings will now be automatically distributed to the proper
|
|
|
|
|
app or project message file. See :ref:`how-to-create-language-files` for
|
|
|
|
|
details.
|
|
|
|
|
|
2014-03-06 17:13:22 +08:00
|
|
|
|
* The :djadmin:`makemessages` command now always adds the ``--previous``
|
|
|
|
|
command line flag to the ``msgmerge`` command, keeping previously translated
|
|
|
|
|
strings in po files for fuzzy strings.
|
|
|
|
|
|
2013-05-19 18:20:34 +08:00
|
|
|
|
* The following settings to adjust the language cookie options were introduced:
|
|
|
|
|
:setting:`LANGUAGE_COOKIE_AGE`, :setting:`LANGUAGE_COOKIE_DOMAIN`
|
|
|
|
|
and :setting:`LANGUAGE_COOKIE_PATH`.
|
|
|
|
|
|
2014-02-19 17:21:10 +08:00
|
|
|
|
* Added :ref:`format definitions <format-localization>` for Esperanto.
|
|
|
|
|
|
2013-08-27 21:39:56 +08:00
|
|
|
|
Management Commands
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
2014-07-26 19:21:52 +08:00
|
|
|
|
* The :djadminopt:`--no-color` option for ``django-admin`` allows you to
|
2013-08-27 21:39:56 +08:00
|
|
|
|
disable the colorization of management command output.
|
|
|
|
|
|
2012-08-01 09:49:01 +08:00
|
|
|
|
* The new :djadminopt:`--natural-foreign` and :djadminopt:`--natural-primary`
|
|
|
|
|
options for :djadmin:`dumpdata`, and the new ``use_natural_foreign_keys`` and
|
|
|
|
|
``use_natural_primary_keys`` arguments for ``serializers.serialize()``, allow
|
|
|
|
|
the use of natural primary keys when serializing.
|
|
|
|
|
|
2013-01-06 06:43:01 +08:00
|
|
|
|
* It is no longer necessary to provide the cache table name or the
|
|
|
|
|
:djadminopt:`--database` option for the :djadmin:`createcachetable` command.
|
|
|
|
|
Django takes this information from your settings file. If you have configured
|
|
|
|
|
multiple caches or multiple databases, all cache tables are created.
|
|
|
|
|
|
2013-11-05 06:28:38 +08:00
|
|
|
|
* The :djadmin:`runserver` command received several improvements:
|
2013-10-14 13:33:45 +08:00
|
|
|
|
|
2013-12-15 21:42:58 +08:00
|
|
|
|
* On Linux systems, if pyinotify_ is installed, the development server will
|
|
|
|
|
reload immediately when a file is changed. Previously, it polled the
|
|
|
|
|
filesystem for changes every second. That caused a small delay before
|
|
|
|
|
reloads and reduced battery life on laptops.
|
2013-11-05 06:28:38 +08:00
|
|
|
|
|
|
|
|
|
.. _pyinotify: https://pypi.python.org/pypi/pyinotify
|
|
|
|
|
|
2013-11-06 04:02:33 +08:00
|
|
|
|
* In addition, the development server automatically reloads when a
|
|
|
|
|
translation file is updated, i.e. after running
|
|
|
|
|
:djadmin:`compilemessages`.
|
2013-11-02 17:28:22 +08:00
|
|
|
|
|
2013-11-09 17:13:29 +08:00
|
|
|
|
* All HTTP requests are logged to the console, including requests for static
|
|
|
|
|
files or ``favicon.ico`` that used to be filtered out.
|
|
|
|
|
|
2013-12-03 10:11:59 +08:00
|
|
|
|
* Management commands can now produce syntax colored output under Windows if
|
|
|
|
|
the ANSICON third-party tool is installed and active.
|
|
|
|
|
|
2014-02-09 20:37:14 +08:00
|
|
|
|
* :djadmin:`collectstatic` command with symlink option is now supported on
|
|
|
|
|
Windows NT 6 (Windows Vista and newer).
|
|
|
|
|
|
2014-12-27 02:56:08 +08:00
|
|
|
|
* Initial SQL data now works better if the sqlparse_ Python library is
|
2014-04-26 16:22:48 +08:00
|
|
|
|
installed.
|
|
|
|
|
|
2014-04-28 03:05:25 +08:00
|
|
|
|
Note that it's deprecated in favor of the
|
|
|
|
|
:class:`~django.db.migrations.operations.RunSQL` operation of migrations,
|
|
|
|
|
which benefits from the improved behavior.
|
2014-04-26 16:22:48 +08:00
|
|
|
|
|
|
|
|
|
.. _sqlparse: https://pypi.python.org/pypi/sqlparse
|
|
|
|
|
|
2013-08-27 21:39:56 +08:00
|
|
|
|
Models
|
|
|
|
|
^^^^^^
|
|
|
|
|
|
2013-09-08 17:23:37 +08:00
|
|
|
|
* The :meth:`QuerySet.update_or_create()
|
|
|
|
|
<django.db.models.query.QuerySet.update_or_create>` method was added.
|
|
|
|
|
|
2013-08-01 23:31:34 +08:00
|
|
|
|
* The new :attr:`~django.db.models.Options.default_permissions` model
|
|
|
|
|
``Meta`` option allows you to customize (or disable) creation of the default
|
|
|
|
|
add, change, and delete permissions.
|
|
|
|
|
|
2013-08-12 19:30:38 +08:00
|
|
|
|
* Explicit :class:`~django.db.models.OneToOneField` for
|
|
|
|
|
:ref:`multi-table-inheritance` are now discovered in abstract classes.
|
|
|
|
|
|
2014-11-11 08:47:47 +08:00
|
|
|
|
* It is now possible to avoid creating a backward relation for
|
2013-08-20 13:52:32 +08:00
|
|
|
|
:class:`~django.db.models.OneToOneField` by setting its
|
|
|
|
|
:attr:`~django.db.models.ForeignKey.related_name` to
|
2013-11-05 12:11:51 +08:00
|
|
|
|
``'+'`` or ending it with ``'+'``.
|
2013-08-20 13:52:32 +08:00
|
|
|
|
|
2013-02-22 06:02:18 +08:00
|
|
|
|
* :class:`F expressions <django.db.models.F>` support the power operator
|
|
|
|
|
(``**``).
|
|
|
|
|
|
2013-11-22 01:14:16 +08:00
|
|
|
|
* The ``remove()`` and ``clear()`` methods of the related managers created by
|
|
|
|
|
``ForeignKey`` and ``GenericForeignKey`` now accept the ``bulk`` keyword
|
|
|
|
|
argument to control whether or not to perform operations in bulk
|
|
|
|
|
(i.e. using ``QuerySet.update()``). Defaults to ``True``.
|
|
|
|
|
|
2013-12-03 17:24:45 +08:00
|
|
|
|
* It is now possible to use ``None`` as a query value for the :lookup:`iexact`
|
|
|
|
|
lookup.
|
|
|
|
|
|
2014-02-02 03:23:31 +08:00
|
|
|
|
* It is now possible to pass a callable as value for the attribute
|
2014-02-13 23:32:50 +08:00
|
|
|
|
:attr:`~django.db.models.ForeignKey.limit_choices_to` when defining a
|
|
|
|
|
``ForeignKey`` or ``ManyToManyField``.
|
2014-02-02 03:23:31 +08:00
|
|
|
|
|
2014-02-16 05:44:14 +08:00
|
|
|
|
* Calling :meth:`only() <django.db.models.query.QuerySet.only>` and
|
|
|
|
|
:meth:`defer() <django.db.models.query.QuerySet.defer>` on the result of
|
|
|
|
|
:meth:`QuerySet.values() <django.db.models.query.QuerySet.values>` now raises
|
|
|
|
|
an error (before that, it would either result in a database error or
|
|
|
|
|
incorrect data).
|
|
|
|
|
|
2014-03-02 03:06:15 +08:00
|
|
|
|
* You can use a single list for :attr:`~django.db.models.Options.index_together`
|
|
|
|
|
(rather than a list of lists) when specifying a single set of fields.
|
|
|
|
|
|
2014-02-20 02:01:55 +08:00
|
|
|
|
* Custom intermediate models having more than one foreign key to any of the
|
|
|
|
|
models participating in a many-to-many relationship are now permitted,
|
|
|
|
|
provided you explicitly specify which foreign keys should be used by setting
|
|
|
|
|
the new :attr:`ManyToManyField.through_fields <django.db.models.ManyToManyField.through_fields>`
|
|
|
|
|
argument.
|
|
|
|
|
|
2014-03-10 23:17:57 +08:00
|
|
|
|
* Assigning a model instance to a non-relation field will now throw an error.
|
|
|
|
|
Previously this used to work if the field accepted integers as input as it
|
|
|
|
|
took the primary key.
|
|
|
|
|
|
2014-03-04 09:12:42 +08:00
|
|
|
|
* Integer fields are now validated against database backend specific min and
|
|
|
|
|
max values based on their :meth:`internal_type <django.db.models.Field.get_internal_type>`.
|
|
|
|
|
Previously model field validation didn't prevent values out of their associated
|
|
|
|
|
column data type range from being saved resulting in an integrity error.
|
|
|
|
|
|
2014-04-26 15:34:20 +08:00
|
|
|
|
* It is now possible to explicitly :meth:`~django.db.models.query.QuerySet.order_by`
|
|
|
|
|
a relation ``_id`` field by using its attribute name.
|
|
|
|
|
|
2013-08-27 21:39:56 +08:00
|
|
|
|
Signals
|
|
|
|
|
^^^^^^^
|
2013-06-05 04:41:49 +08:00
|
|
|
|
|
2013-08-27 21:39:56 +08:00
|
|
|
|
* The ``enter`` argument was added to the
|
|
|
|
|
:data:`~django.test.signals.setting_changed` signal.
|
|
|
|
|
|
2013-11-05 12:11:51 +08:00
|
|
|
|
* The model signals can be now be connected to using a ``str`` of the
|
|
|
|
|
``'app_label.ModelName'`` form – just like related fields – to lazily
|
|
|
|
|
reference their senders.
|
|
|
|
|
|
2013-08-27 21:39:56 +08:00
|
|
|
|
Templates
|
|
|
|
|
^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
* The :meth:`Context.push() <django.template.Context.push>` method now returns
|
|
|
|
|
a context manager which automatically calls :meth:`pop()
|
|
|
|
|
<django.template.Context.pop>` upon exiting the ``with`` statement.
|
|
|
|
|
Additionally, :meth:`push() <django.template.Context.push>` now accepts
|
|
|
|
|
parameters that are passed to the ``dict`` constructor used to build the new
|
|
|
|
|
context level.
|
2013-08-10 16:13:41 +08:00
|
|
|
|
|
2014-02-16 21:50:27 +08:00
|
|
|
|
* The new :meth:`Context.flatten() <django.template.Context.flatten>` method
|
|
|
|
|
returns a ``Context``'s stack as one flat dictionary.
|
|
|
|
|
|
|
|
|
|
* ``Context`` objects can now be compared for equality (internally, this
|
|
|
|
|
uses :meth:`Context.flatten() <django.template.Context.flatten>` so the
|
|
|
|
|
internal structure of each ``Context``'s stack doesn't matter as long as their
|
|
|
|
|
flattened version is identical).
|
|
|
|
|
|
2014-05-11 10:13:50 +08:00
|
|
|
|
* The :ttag:`widthratio` template tag now accepts an ``"as"`` parameter to
|
|
|
|
|
capture the result in a variable.
|
2013-08-14 22:14:32 +08:00
|
|
|
|
|
2013-08-28 20:17:20 +08:00
|
|
|
|
* The :ttag:`include` template tag will now also accept anything with a
|
|
|
|
|
``render()`` method (such as a ``Template``) as an argument. String
|
|
|
|
|
arguments will be looked up using
|
|
|
|
|
:func:`~django.template.loader.get_template` as always.
|
|
|
|
|
|
2013-08-29 16:58:56 +08:00
|
|
|
|
* It is now possible to :ttag:`include` templates recursively.
|
|
|
|
|
|
2013-08-31 03:08:40 +08:00
|
|
|
|
* Template objects now have an origin attribute set when
|
2015-02-15 22:42:05 +08:00
|
|
|
|
``TEMPLATE_DEBUG`` is ``True``. This allows template origins to be
|
2013-08-31 03:08:40 +08:00
|
|
|
|
inspected and logged outside of the ``django.template`` infrastructure.
|
|
|
|
|
|
2013-10-23 22:56:13 +08:00
|
|
|
|
* ``TypeError`` exceptions are no longer silenced when raised during the
|
2013-09-08 21:07:12 +08:00
|
|
|
|
rendering of a template.
|
|
|
|
|
|
2013-09-16 05:51:24 +08:00
|
|
|
|
* The following functions now accept a ``dirs`` parameter which is a list or
|
2014-12-18 05:51:42 +08:00
|
|
|
|
tuple to override ``TEMPLATE_DIRS``:
|
2013-09-16 05:51:24 +08:00
|
|
|
|
|
|
|
|
|
* :func:`django.template.loader.get_template()`
|
|
|
|
|
* :func:`django.template.loader.select_template()`
|
|
|
|
|
* :func:`django.shortcuts.render()`
|
|
|
|
|
* :func:`django.shortcuts.render_to_response()`
|
|
|
|
|
|
2013-01-10 17:27:20 +08:00
|
|
|
|
* The :tfilter:`time` filter now accepts timezone-related :ref:`format
|
2013-09-23 02:41:24 +08:00
|
|
|
|
specifiers <date-and-time-formatting-specifiers>` ``'e'``, ``'O'`` , ``'T'``
|
|
|
|
|
and ``'Z'`` and is able to digest :ref:`time-zone-aware
|
|
|
|
|
<naive_vs_aware_datetimes>` ``datetime`` instances performing the expected
|
|
|
|
|
rendering.
|
|
|
|
|
|
2013-10-04 05:36:21 +08:00
|
|
|
|
* The :ttag:`cache` tag will now try to use the cache called
|
|
|
|
|
"template_fragments" if it exists and fall back to using the default cache
|
|
|
|
|
otherwise. It also now accepts an optional ``using`` keyword argument to
|
|
|
|
|
control which cache it uses.
|
|
|
|
|
|
2013-01-10 17:27:20 +08:00
|
|
|
|
* The new :tfilter:`truncatechars_html` filter truncates a string to be no
|
|
|
|
|
longer than the specified number of characters, taking HTML into account.
|
|
|
|
|
|
2014-02-15 01:28:51 +08:00
|
|
|
|
Requests and Responses
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^
|
2013-10-09 02:30:29 +08:00
|
|
|
|
|
|
|
|
|
* The new :attr:`HttpRequest.scheme <django.http.HttpRequest.scheme>` attribute
|
|
|
|
|
specifies the scheme of the request (``http`` or ``https`` normally).
|
|
|
|
|
|
2014-02-15 01:28:51 +08:00
|
|
|
|
|
2014-02-14 11:48:44 +08:00
|
|
|
|
* The shortcut :func:`redirect() <django.shortcuts.redirect>` now supports
|
|
|
|
|
relative URLs.
|
|
|
|
|
|
2014-02-15 01:28:51 +08:00
|
|
|
|
* The new :class:`~django.http.JsonResponse` subclass of
|
|
|
|
|
:class:`~django.http.HttpResponse` helps easily create JSON-encoded responses.
|
|
|
|
|
|
2013-09-10 21:49:39 +08:00
|
|
|
|
Tests
|
|
|
|
|
^^^^^
|
|
|
|
|
|
|
|
|
|
* :class:`~django.test.runner.DiscoverRunner` has two new attributes,
|
|
|
|
|
:attr:`~django.test.runner.DiscoverRunner.test_suite` and
|
|
|
|
|
:attr:`~django.test.runner.DiscoverRunner.test_runner`, which facilitate
|
|
|
|
|
overriding the way tests are collected and run.
|
|
|
|
|
|
2013-09-08 05:13:57 +08:00
|
|
|
|
* The ``fetch_redirect_response`` argument was added to
|
|
|
|
|
:meth:`~django.test.SimpleTestCase.assertRedirects`. Since the test
|
|
|
|
|
client can't fetch externals URLs, this allows you to use ``assertRedirects``
|
|
|
|
|
with redirects that aren't part of your Django app.
|
|
|
|
|
|
2013-10-29 03:34:09 +08:00
|
|
|
|
* Correct handling of scheme when making comparisons in
|
|
|
|
|
:meth:`~django.test.SimpleTestCase.assertRedirects`.
|
|
|
|
|
|
2013-10-28 22:00:54 +08:00
|
|
|
|
* The ``secure`` argument was added to all the request methods of
|
|
|
|
|
:class:`~django.test.Client`. If ``True``, the request will be made
|
|
|
|
|
through HTTPS.
|
|
|
|
|
|
2013-12-12 22:48:54 +08:00
|
|
|
|
* :meth:`~django.test.TransactionTestCase.assertNumQueries` now prints
|
|
|
|
|
out the list of executed queries if the assertion fails.
|
|
|
|
|
|
2013-11-19 16:44:30 +08:00
|
|
|
|
* The ``WSGIRequest`` instance generated by the test handler is now attached to
|
|
|
|
|
the :attr:`django.test.Response.wsgi_request` attribute.
|
|
|
|
|
|
2014-01-20 08:45:29 +08:00
|
|
|
|
* The database settings for testing have been collected into a dictionary
|
|
|
|
|
named :setting:`TEST <DATABASE-TEST>`.
|
|
|
|
|
|
2014-03-22 19:25:26 +08:00
|
|
|
|
Utilities
|
|
|
|
|
^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
* Improved :func:`~django.utils.html.strip_tags` accuracy (but it still cannot
|
|
|
|
|
guarantee an HTML-safe result, as stated in the documentation).
|
|
|
|
|
|
2013-12-21 07:15:39 +08:00
|
|
|
|
Validators
|
|
|
|
|
^^^^^^^^^^
|
|
|
|
|
|
2014-03-13 19:23:12 +08:00
|
|
|
|
* :class:`~django.core.validators.RegexValidator` now accepts the optional
|
|
|
|
|
:attr:`~django.core.validators.RegexValidator.flags` and
|
|
|
|
|
Boolean :attr:`~django.core.validators.RegexValidator.inverse_match` arguments.
|
|
|
|
|
The :attr:`~django.core.validators.RegexValidator.inverse_match` attribute
|
|
|
|
|
determines if the :exc:`~django.core.exceptions.ValidationError` should
|
2013-07-22 08:27:56 +08:00
|
|
|
|
be raised when the regular expression pattern matches (``True``) or does not
|
2014-03-13 19:23:12 +08:00
|
|
|
|
match (``False``, by default) the provided ``value``. The
|
|
|
|
|
:attr:`~django.core.validators.RegexValidator.flags` attribute sets the flags
|
|
|
|
|
used when compiling a regular expression string.
|
2013-07-22 08:27:56 +08:00
|
|
|
|
|
2013-12-21 07:15:39 +08:00
|
|
|
|
* :class:`~django.core.validators.URLValidator` now accepts an optional
|
|
|
|
|
``schemes`` argument which allows customization of the accepted URI schemes
|
|
|
|
|
(instead of the defaults ``http(s)`` and ``ftp(s)``).
|
|
|
|
|
|
2014-02-22 23:00:23 +08:00
|
|
|
|
* :func:`~django.core.validators.validate_email` now accepts addresses with
|
|
|
|
|
IPv6 literals, like ``example@[2001:db8::1]``, as specified in RFC 5321.
|
|
|
|
|
|
2013-07-01 19:53:06 +08:00
|
|
|
|
Backwards incompatible changes in 1.7
|
|
|
|
|
=====================================
|
|
|
|
|
|
|
|
|
|
.. warning::
|
|
|
|
|
|
|
|
|
|
In addition to the changes outlined in this section, be sure to review the
|
2014-05-30 06:58:12 +08:00
|
|
|
|
:ref:`deprecation plan <deprecation-removed-in-1.7>` for any features that
|
2013-07-01 19:53:06 +08:00
|
|
|
|
have been removed. If you haven't updated your code within the
|
|
|
|
|
deprecation timeline for a given feature, its removal may appear as a
|
|
|
|
|
backwards incompatible change.
|
|
|
|
|
|
2014-12-27 01:34:26 +08:00
|
|
|
|
``allow_syncdb`` / ``allow_migrate``
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2013-07-30 19:34:31 +08:00
|
|
|
|
|
|
|
|
|
While Django will still look at ``allow_syncdb`` methods even though they
|
|
|
|
|
should be renamed to ``allow_migrate``, there is a subtle difference in which
|
|
|
|
|
models get passed to these methods.
|
|
|
|
|
|
|
|
|
|
For apps with migrations, ``allow_migrate`` will now get passed
|
|
|
|
|
:ref:`historical models <historical-models>`, which are special versioned models
|
|
|
|
|
without custom attributes, methods or managers. Make sure your ``allow_migrate``
|
|
|
|
|
methods are only referring to fields or other items in ``model._meta``.
|
|
|
|
|
|
2014-02-09 20:22:29 +08:00
|
|
|
|
initial_data
|
|
|
|
|
~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Apps with migrations will not load ``initial_data`` fixtures when they have
|
|
|
|
|
finished migrating. Apps without migrations will continue to load these fixtures
|
2014-03-01 00:44:03 +08:00
|
|
|
|
during the phase of ``migrate`` which emulates the old ``syncdb`` behavior,
|
2014-02-09 20:22:29 +08:00
|
|
|
|
but any new apps will not have this support.
|
|
|
|
|
|
|
|
|
|
Instead, you are encouraged to load initial data in migrations if you need it
|
|
|
|
|
(using the ``RunPython`` operation and your model classes);
|
|
|
|
|
this has the added advantage that your initial data will not need updating
|
|
|
|
|
every time you change the schema.
|
|
|
|
|
|
2014-07-26 00:09:15 +08:00
|
|
|
|
Additionally, like the rest of Django's old ``syncdb`` code, ``initial_data``
|
|
|
|
|
has been started down the deprecation path and will be removed in Django 1.9.
|
|
|
|
|
|
2014-05-07 14:06:41 +08:00
|
|
|
|
deconstruct() and serializability
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Django now requires all Field classes and all of their constructor arguments
|
|
|
|
|
to be serializable. If you modify the constructor signature in your custom
|
|
|
|
|
Field in any way, you'll need to implement a deconstruct() method;
|
|
|
|
|
we've expanded the custom field documentation with :ref:`instructions
|
|
|
|
|
on implementing this method <custom-field-deconstruct-method>`.
|
|
|
|
|
|
|
|
|
|
The requirement for all field arguments to be
|
|
|
|
|
:ref:`serializable <migration-serializing>` means that any custom class
|
|
|
|
|
instances being passed into Field constructors - things like custom Storage
|
|
|
|
|
subclasses, for instance - need to have a :ref:`deconstruct method defined on
|
|
|
|
|
them as well <custom-deconstruct-method>`, though Django provides a handy
|
|
|
|
|
class decorator that will work for most applications.
|
|
|
|
|
|
2013-12-25 02:00:29 +08:00
|
|
|
|
App-loading changes
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
2013-12-31 21:09:19 +08:00
|
|
|
|
Start-up sequence
|
|
|
|
|
^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
Django 1.7 loads application configurations and models as soon as it starts.
|
|
|
|
|
While this behavior is more straightforward and is believed to be more robust,
|
2014-04-25 23:39:49 +08:00
|
|
|
|
regressions cannot be ruled out. See :ref:`applications-troubleshooting` for
|
2014-04-13 23:18:02 +08:00
|
|
|
|
solutions to some problems you may encounter.
|
2014-01-25 05:43:00 +08:00
|
|
|
|
|
2013-12-31 21:09:19 +08:00
|
|
|
|
Standalone scripts
|
|
|
|
|
^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
If you're using Django in a plain Python script — rather than a management
|
|
|
|
|
command — and you rely on the :envvar:`DJANGO_SETTINGS_MODULE` environment
|
|
|
|
|
variable, you must now explicitly initialize Django at the beginning of your
|
|
|
|
|
script with::
|
|
|
|
|
|
|
|
|
|
>>> import django
|
|
|
|
|
>>> django.setup()
|
|
|
|
|
|
2014-06-21 21:00:35 +08:00
|
|
|
|
Otherwise, you will hit an ``AppRegistryNotReady`` exception.
|
2013-12-31 21:09:19 +08:00
|
|
|
|
|
2014-09-07 01:02:06 +08:00
|
|
|
|
WSGI scripts
|
2014-09-19 19:05:20 +08:00
|
|
|
|
^^^^^^^^^^^^
|
2014-09-07 01:02:06 +08:00
|
|
|
|
|
|
|
|
|
Until Django 1.3, the recommended way to create a WSGI application was::
|
|
|
|
|
|
|
|
|
|
import django.core.handlers.wsgi
|
|
|
|
|
application = django.core.handlers.wsgi.WSGIHandler()
|
|
|
|
|
|
|
|
|
|
In Django 1.4, support for WSGI was improved and the API changed to::
|
|
|
|
|
|
|
|
|
|
from django.core.wsgi import get_wsgi_application
|
|
|
|
|
application = get_wsgi_application()
|
|
|
|
|
|
|
|
|
|
If you're still using the former style in your WSGI script, you need to
|
|
|
|
|
upgrade to the latter, or you will hit an ``AppRegistryNotReady`` exception.
|
|
|
|
|
|
2014-01-01 00:25:57 +08:00
|
|
|
|
App registry consistency
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
It is no longer possible to have multiple installed applications with the same
|
|
|
|
|
label. In previous versions of Django, this didn't always work correctly, but
|
|
|
|
|
didn't crash outright either.
|
|
|
|
|
|
|
|
|
|
If you have two apps with the same label, you should create an
|
|
|
|
|
:class:`~django.apps.AppConfig` for one of them and override its
|
|
|
|
|
:class:`~django.apps.AppConfig.label` there. You should then adjust your code
|
|
|
|
|
wherever it references this application or its models with the old label.
|
|
|
|
|
|
2014-01-05 16:32:22 +08:00
|
|
|
|
It isn't possible to import the same model twice through different paths any
|
|
|
|
|
more. As of Django 1.6, this may happen only if you're manually putting a
|
|
|
|
|
directory and a subdirectory on :envvar:`PYTHONPATH`. Refer to the section on
|
|
|
|
|
the new project layout in the :doc:`1.4 release notes </releases/1.4>` for
|
|
|
|
|
migration instructions.
|
|
|
|
|
|
2014-01-11 06:06:19 +08:00
|
|
|
|
You should make sure that:
|
|
|
|
|
|
|
|
|
|
* All models are defined in applications that are listed in
|
|
|
|
|
:setting:`INSTALLED_APPS` or have an explicit
|
|
|
|
|
:attr:`~django.db.models.Options.app_label`.
|
|
|
|
|
|
|
|
|
|
* Models aren't imported as a side-effect of loading their application.
|
|
|
|
|
Specifically, you shouldn't import models in the root module of an
|
|
|
|
|
application nor in the module that define its configuration class.
|
|
|
|
|
|
|
|
|
|
Django will enforce these requirements as of version 1.9, after a deprecation
|
|
|
|
|
period.
|
2014-01-01 00:25:57 +08:00
|
|
|
|
|
2013-12-31 21:09:19 +08:00
|
|
|
|
Subclassing AppCommand
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
|
Subclasses of :class:`~django.core.management.AppCommand` must now implement a
|
|
|
|
|
:meth:`~django.core.management.AppCommand.handle_app_config` method instead of
|
|
|
|
|
``handle_app()``. This method receives an :class:`~django.apps.AppConfig`
|
|
|
|
|
instance instead of a models module.
|
|
|
|
|
|
|
|
|
|
Introspecting applications
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
2013-12-25 06:43:47 +08:00
|
|
|
|
|
2013-12-25 02:00:29 +08:00
|
|
|
|
Since :setting:`INSTALLED_APPS` now supports application configuration classes
|
|
|
|
|
in addition to application modules, you should review code that accesses this
|
|
|
|
|
setting directly and use the app registry (:attr:`django.apps.apps`) instead.
|
|
|
|
|
|
2013-12-31 21:09:19 +08:00
|
|
|
|
The app registry has preserved some features of the old app cache. Even though
|
|
|
|
|
the app cache was a private API, obsolete methods and arguments will be
|
|
|
|
|
removed through a standard deprecation path, with the exception of the
|
|
|
|
|
following changes that take effect immediately:
|
2013-12-28 21:55:54 +08:00
|
|
|
|
|
2014-04-26 22:00:15 +08:00
|
|
|
|
* ``get_model`` raises :exc:`LookupError` instead of returning ``None`` when no
|
|
|
|
|
model is found.
|
2013-12-28 21:55:54 +08:00
|
|
|
|
|
2013-12-29 01:27:33 +08:00
|
|
|
|
* The ``only_installed`` argument of ``get_model`` and ``get_models`` no
|
|
|
|
|
longer exists, nor does the ``seed_cache`` argument of ``get_model``.
|
2013-12-25 02:00:29 +08:00
|
|
|
|
|
2014-01-02 01:05:12 +08:00
|
|
|
|
Management commands and order of :setting:`INSTALLED_APPS`
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
When several applications provide management commands with the same name,
|
|
|
|
|
Django loads the command from the application that comes first in
|
|
|
|
|
:setting:`INSTALLED_APPS`. Previous versions loaded the command from the
|
2014-01-02 17:06:52 +08:00
|
|
|
|
application that came last.
|
2014-01-02 01:05:12 +08:00
|
|
|
|
|
|
|
|
|
This brings discovery of management commands in line with other parts of
|
|
|
|
|
Django that rely on the order of :setting:`INSTALLED_APPS`, such as static
|
|
|
|
|
files, templates, and translations.
|
|
|
|
|
|
2014-07-01 21:48:00 +08:00
|
|
|
|
.. _validation-error-constructor-and-internal-storage:
|
|
|
|
|
|
|
|
|
|
``ValidationError`` constructor and internal storage
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
The behavior of the ``ValidationError`` constructor has changed when it
|
|
|
|
|
receives a container of errors as an argument (e.g. a ``list`` or an
|
|
|
|
|
``ErrorList``):
|
|
|
|
|
|
|
|
|
|
* It converts any strings it finds to instances of ``ValidationError``
|
|
|
|
|
before adding them to its internal storage.
|
|
|
|
|
|
|
|
|
|
* It doesn't store the given container but rather copies its content to its
|
|
|
|
|
own internal storage; previously the container itself was added to the
|
|
|
|
|
``ValidationError`` instance and used as internal storage.
|
|
|
|
|
|
|
|
|
|
This means that if you access the ``ValidationError`` internal storages, such
|
|
|
|
|
as ``error_list``; ``error_dict``; or the return value of
|
|
|
|
|
``update_error_dict()`` you may find instances of ``ValidationError`` where you
|
|
|
|
|
would have previously found strings.
|
|
|
|
|
|
|
|
|
|
Also if you directly assigned the return value of ``update_error_dict()``
|
|
|
|
|
to ``Form._errors`` you may inadvertently add `list` instances where
|
|
|
|
|
``ErrorList`` instances are expected. This is a problem because unlike a
|
|
|
|
|
simple `list`, an ``ErrorList`` knows how to handle instances of
|
|
|
|
|
``ValidationError``.
|
|
|
|
|
|
|
|
|
|
Most use-cases that warranted using these private APIs are now covered by
|
|
|
|
|
the newly introduced :meth:`Form.add_error() <django.forms.Form.add_error()>`
|
|
|
|
|
method::
|
|
|
|
|
|
|
|
|
|
# Old pattern:
|
|
|
|
|
try:
|
|
|
|
|
# ...
|
|
|
|
|
except ValidationError as e:
|
|
|
|
|
self._errors = e.update_error_dict(self._errors)
|
|
|
|
|
|
|
|
|
|
# New pattern:
|
|
|
|
|
try:
|
|
|
|
|
# ...
|
|
|
|
|
except ValidationError as e:
|
|
|
|
|
self.add_error(None, e)
|
|
|
|
|
|
|
|
|
|
If you need both Django <= 1.6 and 1.7 compatibility you can't use
|
|
|
|
|
:meth:`Form.add_error() <django.forms.Form.add_error()>` since it
|
|
|
|
|
wasn't available before Django 1.7, but you can use the following
|
|
|
|
|
workaround to convert any ``list`` into ``ErrorList``::
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
# ...
|
|
|
|
|
except ValidationError as e:
|
|
|
|
|
self._errors = e.update_error_dict(self._errors)
|
|
|
|
|
|
|
|
|
|
# Additional code to ensure ``ErrorDict`` is exclusively
|
|
|
|
|
# composed of ``ErrorList`` instances.
|
|
|
|
|
for field, error_list in self._errors.items():
|
|
|
|
|
if not isinstance(error_list, self.error_class):
|
|
|
|
|
self._errors[field] = self.error_class(error_list)
|
|
|
|
|
|
2013-11-24 00:50:28 +08:00
|
|
|
|
Behavior of ``LocMemCache`` regarding pickle errors
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
An inconsistency existed in previous versions of Django regarding how pickle
|
|
|
|
|
errors are handled by different cache backends.
|
|
|
|
|
``django.core.cache.backends.locmem.LocMemCache`` used to fail silently when
|
|
|
|
|
such an error occurs, which is inconsistent with other backends and leads to
|
|
|
|
|
cache-specific errors. This has been fixed in Django 1.7, see
|
2014-12-19 22:54:29 +08:00
|
|
|
|
:ticket:`21200` for more details.
|
2013-11-24 00:50:28 +08:00
|
|
|
|
|
2013-12-27 12:14:08 +08:00
|
|
|
|
Cache keys are now generated from the request's absolute URL
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Previous versions of Django generated cache keys using a request's path and
|
|
|
|
|
query string but not the scheme or host. If a Django application was serving
|
|
|
|
|
multiple subdomains or domains, cache keys could collide. In Django 1.7, cache
|
|
|
|
|
keys vary by the absolute URL of the request including scheme, host, path, and
|
|
|
|
|
query string. For example, the URL portion of a cache key is now generated from
|
|
|
|
|
``http://www.example.com/path/to/?key=val`` rather than ``/path/to/?key=val``.
|
|
|
|
|
The cache keys generated by Django 1.7 will be different from the keys
|
|
|
|
|
generated by older versions of Django. After upgrading to Django 1.7, the first
|
2014-11-14 01:01:22 +08:00
|
|
|
|
request to any previously cached URL will be a cache miss.
|
2013-12-27 12:14:08 +08:00
|
|
|
|
|
2013-09-30 13:05:43 +08:00
|
|
|
|
Passing ``None`` to ``Manager.db_manager()``
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
In previous versions of Django, it was possible to use
|
|
|
|
|
``db_manager(using=None)`` on a model manager instance to obtain a manager
|
|
|
|
|
instance using default routing behavior, overriding any manually specified
|
|
|
|
|
database routing. In Django 1.7, a value of ``None`` passed to db_manager will
|
|
|
|
|
produce a router that *retains* any manually assigned database routing -- the
|
|
|
|
|
manager will *not* be reset. This was necessary to resolve an inconsistency in
|
2014-12-19 22:54:29 +08:00
|
|
|
|
the way routing information cascaded over joins. See :ticket:`13724` for more
|
2013-09-30 13:05:43 +08:00
|
|
|
|
details.
|
|
|
|
|
|
2013-09-08 15:04:31 +08:00
|
|
|
|
pytz may be required
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
If your project handles datetimes before 1970 or after 2037 and Django raises
|
2014-04-26 22:00:15 +08:00
|
|
|
|
a :exc:`ValueError` when encountering them, you will have to install pytz_. You
|
|
|
|
|
may be affected by this problem if you use Django's time zone-related date
|
|
|
|
|
formats or :mod:`django.contrib.syndication`.
|
2013-09-08 15:04:31 +08:00
|
|
|
|
|
2014-01-31 22:18:55 +08:00
|
|
|
|
.. _pytz: https://pypi.python.org/pypi/pytz/
|
|
|
|
|
|
2013-09-27 07:35:53 +08:00
|
|
|
|
``remove()`` and ``clear()`` methods of related managers
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
The ``remove()`` and ``clear()`` methods of the related managers created by
|
|
|
|
|
``ForeignKey``, ``GenericForeignKey``, and ``ManyToManyField`` suffered from a
|
|
|
|
|
number of issues. Some operations ran multiple data modifying queries without
|
|
|
|
|
wrapping them in a transaction, and some operations didn't respect default
|
|
|
|
|
filtering when it was present (i.e. when the default manager on the related
|
|
|
|
|
model implemented a custom ``get_queryset()``).
|
|
|
|
|
|
|
|
|
|
Fixing the issues introduced some backward incompatible changes:
|
|
|
|
|
|
|
|
|
|
- The default implementation of ``remove()`` for ``ForeignKey`` related managers
|
|
|
|
|
changed from a series of ``Model.save()`` calls to a single
|
|
|
|
|
``QuerySet.update()`` call. The change means that ``pre_save`` and
|
2013-11-22 01:14:16 +08:00
|
|
|
|
``post_save`` signals aren't sent anymore. You can use the ``bulk=False``
|
|
|
|
|
keyword argument to revert to the previous behavior.
|
2013-09-27 07:35:53 +08:00
|
|
|
|
|
|
|
|
|
- The ``remove()`` and ``clear()`` methods for ``GenericForeignKey`` related
|
|
|
|
|
managers now perform bulk delete. The ``Model.delete()`` method isn't called
|
2013-11-22 01:14:16 +08:00
|
|
|
|
on each instance anymore. You can use the ``bulk=False`` keyword argument to
|
|
|
|
|
revert to the previous behavior.
|
2013-09-27 07:35:53 +08:00
|
|
|
|
|
|
|
|
|
- The ``remove()`` and ``clear()`` methods for ``ManyToManyField`` related
|
|
|
|
|
managers perform nested queries when filtering is involved, which may or
|
|
|
|
|
may not be an issue depending on your database and your data itself.
|
|
|
|
|
See :ref:`this note <nested-queries-performance>` for more details.
|
|
|
|
|
|
2014-01-31 22:18:55 +08:00
|
|
|
|
Admin login redirection strategy
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Historically, the Django admin site passed the request from an unauthorized or
|
|
|
|
|
unauthenticated user directly to the login view, without HTTP redirection. In
|
|
|
|
|
Django 1.7, this behavior changed to conform to a more traditional workflow
|
|
|
|
|
where any unauthorized request to an admin page will be redirected (by HTTP
|
|
|
|
|
status code 302) to the login page, with the ``next`` parameter set to the
|
|
|
|
|
referring path. The user will be redirected there after a successful login.
|
2013-09-08 15:04:31 +08:00
|
|
|
|
|
2014-02-03 06:16:07 +08:00
|
|
|
|
Note also that the admin login form has been updated to not contain the
|
|
|
|
|
``this_is_the_login_form`` field (now unused) and the ``ValidationError`` code
|
|
|
|
|
has been set to the more regular ``invalid_login`` key.
|
|
|
|
|
|
2014-03-31 01:03:35 +08:00
|
|
|
|
``select_for_update()`` requires a transaction
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Historically, queries that use
|
|
|
|
|
:meth:`~django.db.models.query.QuerySet.select_for_update()` could be
|
|
|
|
|
executed in autocommit mode, outside of a transaction. Before Django
|
|
|
|
|
1.6, Django's automatic transactions mode allowed this to be used to
|
|
|
|
|
lock records until the next write operation. Django 1.6 introduced
|
|
|
|
|
database-level autocommit; since then, execution in such a context
|
|
|
|
|
voids the effect of ``select_for_update()``. It is, therefore, assumed
|
2014-04-10 08:40:33 +08:00
|
|
|
|
now to be an error and raises an exception.
|
2014-03-31 01:03:35 +08:00
|
|
|
|
|
|
|
|
|
This change was made because such errors can be caused by including an
|
|
|
|
|
app which expects global transactions (e.g. :setting:`ATOMIC_REQUESTS
|
2014-04-10 08:40:33 +08:00
|
|
|
|
<DATABASE-ATOMIC_REQUESTS>` set to ``True``), or Django's old autocommit
|
2014-03-31 01:03:35 +08:00
|
|
|
|
behavior, in a project which runs without them; and further, such
|
2014-04-10 08:40:33 +08:00
|
|
|
|
errors may manifest as data-corruption bugs. It was also made in
|
|
|
|
|
Django 1.6.3.
|
2014-03-31 01:03:35 +08:00
|
|
|
|
|
2014-04-10 08:40:33 +08:00
|
|
|
|
This change may cause test failures if you use ``select_for_update()``
|
|
|
|
|
in a test class which is a subclass of
|
|
|
|
|
:class:`~django.test.TransactionTestCase` rather than
|
|
|
|
|
:class:`~django.test.TestCase`.
|
2014-03-31 01:03:35 +08:00
|
|
|
|
|
2014-04-20 20:58:29 +08:00
|
|
|
|
Contrib middleware removed from default :setting:`MIDDLEWARE_CLASSES`
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
The :ref:`app-loading refactor <app-loading-refactor-17-release-note>`
|
|
|
|
|
deprecated using models from apps which are not part of the
|
|
|
|
|
:setting:`INSTALLED_APPS` setting. This exposed an incompatibility between
|
|
|
|
|
the default :setting:`INSTALLED_APPS` and :setting:`MIDDLEWARE_CLASSES` in the
|
|
|
|
|
global defaults (``django.conf.global_settings``). To bring these settings in
|
|
|
|
|
sync and prevent deprecation warnings when doing things like testing reusable
|
|
|
|
|
apps with minimal settings,
|
|
|
|
|
:class:`~django.contrib.sessions.middleware.SessionMiddleware`,
|
|
|
|
|
:class:`~django.contrib.auth.middleware.AuthenticationMiddleware`, and
|
|
|
|
|
:class:`~django.contrib.messages.middleware.MessageMiddleware` were removed
|
|
|
|
|
from the defaults. These classes will still be included in the default settings
|
|
|
|
|
generated by :djadmin:`startproject`. Most projects will not be affected by
|
|
|
|
|
this change but if you were not previously declaring the
|
|
|
|
|
:setting:`MIDDLEWARE_CLASSES` in your project settings and relying on the
|
|
|
|
|
global default you should ensure that the new defaults are in line with your
|
|
|
|
|
project's needs. You should also check for any code that accesses
|
|
|
|
|
``django.conf.global_settings.MIDDLEWARE_CLASSES`` directly.
|
|
|
|
|
|
2013-04-20 01:20:23 +08:00
|
|
|
|
Miscellaneous
|
|
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
* The :meth:`django.core.files.uploadhandler.FileUploadHandler.new_file()`
|
|
|
|
|
method is now passed an additional ``content_type_extra`` parameter. If you
|
|
|
|
|
have a custom :class:`~django.core.files.uploadhandler.FileUploadHandler`
|
|
|
|
|
that implements ``new_file()``, be sure it accepts this new parameter.
|
|
|
|
|
|
2014-01-23 22:29:09 +08:00
|
|
|
|
* :class:`ModelFormSet<django.forms.models.BaseModelFormSet>`\s no longer
|
2013-07-12 21:52:18 +08:00
|
|
|
|
delete instances when ``save(commit=False)`` is called. See
|
|
|
|
|
:attr:`~django.forms.formsets.BaseFormSet.can_delete` for instructions on how
|
|
|
|
|
to manually delete objects from deleted forms.
|
|
|
|
|
|
2013-02-24 03:34:59 +08:00
|
|
|
|
* Loading empty fixtures emits a ``RuntimeWarning`` rather than raising
|
|
|
|
|
:class:`~django.core.management.CommandError`.
|
|
|
|
|
|
2013-07-31 19:22:38 +08:00
|
|
|
|
* :func:`django.contrib.staticfiles.views.serve` will now raise an
|
2013-07-31 15:11:49 +08:00
|
|
|
|
:exc:`~django.http.Http404` exception instead of
|
2013-07-31 19:22:38 +08:00
|
|
|
|
:exc:`~django.core.exceptions.ImproperlyConfigured` when :setting:`DEBUG`
|
|
|
|
|
is ``False``. This change removes the need to conditionally add the view to
|
2013-07-31 15:11:49 +08:00
|
|
|
|
your root URLconf, which in turn makes it safe to reverse by name. It also
|
|
|
|
|
removes the ability for visitors to generate spurious HTTP 500 errors by
|
|
|
|
|
requesting static files that don't exist or haven't been collected yet.
|
|
|
|
|
|
2013-08-07 14:51:32 +08:00
|
|
|
|
* The :meth:`django.db.models.Model.__eq__` method is now defined in a
|
|
|
|
|
way where instances of a proxy model and its base model are considered
|
|
|
|
|
equal when primary keys match. Previously only instances of exact same
|
|
|
|
|
class were considered equal on primary key match.
|
|
|
|
|
|
2013-08-14 16:05:01 +08:00
|
|
|
|
* The :meth:`django.db.models.Model.__eq__` method has changed such that
|
|
|
|
|
two ``Model`` instances without primary key values won't be considered
|
|
|
|
|
equal (unless they are the same instance).
|
2013-08-27 21:39:56 +08:00
|
|
|
|
|
2014-05-11 10:13:50 +08:00
|
|
|
|
* The :meth:`django.db.models.Model.__hash__` method will now raise ``TypeError``
|
2013-08-14 16:05:01 +08:00
|
|
|
|
when called on an instance without a primary key value. This is done to
|
|
|
|
|
avoid mutable ``__hash__`` values in containers.
|
|
|
|
|
|
2013-09-10 02:22:29 +08:00
|
|
|
|
* :class:`~django.db.models.AutoField` columns in SQLite databases will now be
|
|
|
|
|
created using the ``AUTOINCREMENT`` option, which guarantees monotonic
|
2013-09-07 00:18:16 +08:00
|
|
|
|
increments. This will cause primary key numbering behavior to change on
|
2013-09-10 02:22:29 +08:00
|
|
|
|
SQLite, becoming consistent with most other SQL databases. This will only
|
|
|
|
|
apply to newly created tables. If you have a database created with an older
|
|
|
|
|
version of Django, you will need to migrate it to take advantage of this
|
|
|
|
|
feature. For example, you could do the following:
|
|
|
|
|
|
|
|
|
|
#) Use :djadmin:`dumpdata` to save your data.
|
|
|
|
|
#) Rename the existing database file (keep it as a backup).
|
|
|
|
|
#) Run :djadmin:`migrate` to create the updated schema.
|
|
|
|
|
#) Use :djadmin:`loaddata` to import the fixtures you exported in (1).
|
2013-09-07 00:18:16 +08:00
|
|
|
|
|
2013-08-29 08:03:21 +08:00
|
|
|
|
* ``django.contrib.auth.models.AbstractUser`` no longer defines a
|
|
|
|
|
:meth:`~django.db.models.Model.get_absolute_url()` method. The old definition
|
|
|
|
|
returned ``"/users/%s/" % urlquote(self.username)`` which was arbitrary
|
|
|
|
|
since applications may or may not define such a url in ``urlpatterns``.
|
|
|
|
|
Define a ``get_absolute_url()`` method on your own custom user object or use
|
|
|
|
|
:setting:`ABSOLUTE_URL_OVERRIDES` if you want a URL for your user.
|
|
|
|
|
|
2013-06-02 01:24:46 +08:00
|
|
|
|
* The static asset-serving functionality of the
|
|
|
|
|
:class:`django.test.LiveServerTestCase` class has been simplified: Now it's
|
|
|
|
|
only able to serve content already present in :setting:`STATIC_ROOT` when
|
|
|
|
|
tests are run. The ability to transparently serve all the static assets
|
|
|
|
|
(similarly to what one gets with :setting:`DEBUG = True <DEBUG>` at
|
|
|
|
|
development-time) has been moved to a new class that lives in the
|
|
|
|
|
``staticfiles`` application (the one actually in charge of such feature):
|
2014-08-28 14:44:26 +08:00
|
|
|
|
:class:`django.contrib.staticfiles.testing.StaticLiveServerTestCase`. In other
|
2013-06-02 01:24:46 +08:00
|
|
|
|
words, ``LiveServerTestCase`` itself is less powerful but at the same time
|
|
|
|
|
has less magic.
|
|
|
|
|
|
|
|
|
|
Rationale behind this is removal of dependency of non-contrib code on
|
|
|
|
|
contrib applications.
|
|
|
|
|
|
2013-09-19 16:38:56 +08:00
|
|
|
|
* The old cache URI syntax (e.g. ``"locmem://"``) is no longer supported. It
|
|
|
|
|
still worked, even though it was not documented or officially supported. If
|
|
|
|
|
you're still using it, please update to the current :setting:`CACHES` syntax.
|
|
|
|
|
|
2013-07-21 03:25:27 +08:00
|
|
|
|
* The default ordering of ``Form`` fields in case of inheritance has changed to
|
|
|
|
|
follow normal Python MRO. Fields are now discovered by iterating through the
|
|
|
|
|
MRO in reverse with the topmost class coming last. This only affects you if
|
|
|
|
|
you relied on the default field ordering while having fields defined on both
|
|
|
|
|
the current class *and* on a parent ``Form``.
|
|
|
|
|
|
2013-11-01 00:27:21 +08:00
|
|
|
|
* The ``required`` argument of
|
2015-01-26 11:28:57 +08:00
|
|
|
|
:class:`~django.forms.SelectDateWidget` has been removed.
|
2013-11-01 00:27:21 +08:00
|
|
|
|
This widget now respects the form field's ``is_required`` attribute like
|
|
|
|
|
other widgets.
|
|
|
|
|
|
2014-02-26 23:03:51 +08:00
|
|
|
|
* ``Widget.is_hidden`` is now a read-only property, getting its value by
|
|
|
|
|
introspecting the presence of ``input_type == 'hidden'``.
|
|
|
|
|
|
2013-10-15 20:15:02 +08:00
|
|
|
|
* :meth:`~django.db.models.query.QuerySet.select_related` now chains in the
|
|
|
|
|
same way as other similar calls like ``prefetch_related``. That is,
|
|
|
|
|
``select_related('foo', 'bar')`` is equivalent to
|
|
|
|
|
``select_related('foo').select_related('bar')``. Previously the latter would
|
|
|
|
|
have been equivalent to ``select_related('bar')``.
|
|
|
|
|
|
2013-12-24 22:57:13 +08:00
|
|
|
|
* GeoDjango dropped support for GEOS < 3.1.
|
|
|
|
|
|
2014-01-13 03:27:08 +08:00
|
|
|
|
* The ``init_connection_state`` method of database backends now executes in
|
|
|
|
|
autocommit mode (unless you set :setting:`AUTOCOMMIT <DATABASE-AUTOCOMMIT>`
|
|
|
|
|
to ``False``). If you maintain a custom database backend, you should check
|
|
|
|
|
that method.
|
|
|
|
|
|
2013-11-24 21:12:22 +08:00
|
|
|
|
* The ``django.db.backends.BaseDatabaseFeatures.allows_primary_key_0``
|
|
|
|
|
attribute has been renamed to ``allows_auto_pk_0`` to better describe it.
|
|
|
|
|
It's ``True`` for all database backends included with Django except MySQL
|
|
|
|
|
which does allow primary keys with value 0. It only forbids *autoincrement*
|
|
|
|
|
primary keys with value 0.
|
|
|
|
|
|
2014-02-08 05:34:56 +08:00
|
|
|
|
* Shadowing model fields defined in a parent model has been forbidden as this
|
2014-11-14 01:01:22 +08:00
|
|
|
|
creates ambiguity in the expected model behavior. In addition, clashing
|
|
|
|
|
fields in the model inheritance hierarchy result in a system check error.
|
2014-02-08 05:34:56 +08:00
|
|
|
|
For example, if you use multi-inheritance, you need to define custom primary
|
|
|
|
|
key fields on parent models, otherwise the default ``id`` fields will clash.
|
2014-04-28 21:28:03 +08:00
|
|
|
|
See :ref:`model-multiple-inheritance-topic` for details.
|
2014-02-08 05:34:56 +08:00
|
|
|
|
|
2014-03-01 07:00:53 +08:00
|
|
|
|
* ``django.utils.translation.parse_accept_lang_header()`` now returns
|
2013-11-12 14:54:01 +08:00
|
|
|
|
lowercase locales, instead of the case as it was provided. As locales should
|
|
|
|
|
be treated case-insensitive this allows us to speed up locale detection.
|
|
|
|
|
|
2014-03-01 07:00:53 +08:00
|
|
|
|
* ``django.utils.translation.get_language_from_path()`` and
|
|
|
|
|
``django.utils.translation.trans_real.get_supported_language_variant()``
|
2013-11-12 14:54:01 +08:00
|
|
|
|
now no longer have a ``supported`` argument.
|
|
|
|
|
|
2014-03-03 04:46:51 +08:00
|
|
|
|
* The ``shortcut`` view in ``django.contrib.contenttypes.views`` now supports
|
|
|
|
|
protocol-relative URLs (e.g. ``//example.com``).
|
|
|
|
|
|
2014-03-04 19:23:32 +08:00
|
|
|
|
* :class:`~django.contrib.contenttypes.fields.GenericRelation` now supports an
|
|
|
|
|
optional ``related_query_name`` argument. Setting ``related_query_name`` adds
|
|
|
|
|
a relation from the related object back to the content type for filtering,
|
|
|
|
|
ordering and other query operations.
|
|
|
|
|
|
2014-04-20 09:39:08 +08:00
|
|
|
|
* When running tests on PostgreSQL, the :setting:`USER` will need read access
|
|
|
|
|
to the built-in ``postgres`` database. This is in lieu of the previous
|
|
|
|
|
behavior of connecting to the actual non-test database.
|
|
|
|
|
|
2014-04-28 02:17:37 +08:00
|
|
|
|
* As part of the :doc:`System check framework </ref/checks>`, :ref:`fields,
|
|
|
|
|
models, and model managers <field-checking>` all implement a ``check()``
|
|
|
|
|
method that is registered with the check framework. If you have an existing
|
|
|
|
|
method called ``check()`` on one of these objects, you will need to rename it.
|
|
|
|
|
|
2014-07-24 03:23:36 +08:00
|
|
|
|
* As noted above in the "Cache" section of "Minor Features", defining the
|
|
|
|
|
:setting:`TIMEOUT <CACHES-TIMEOUT>` argument of the
|
|
|
|
|
:setting:`CACHES` setting as ``None`` will set the cache keys as
|
|
|
|
|
"non-expiring". Previously, with the memcache backend, a
|
|
|
|
|
:setting:`TIMEOUT <CACHES-TIMEOUT>` of ``0`` would set non-expiring keys,
|
|
|
|
|
but this was inconsistent with the set-and-expire (i.e. no caching) behavior
|
|
|
|
|
of ``set("key", "value", timeout=0)``. If you want non-expiring keys,
|
|
|
|
|
please update your settings to use ``None`` instead of ``0`` as the latter
|
|
|
|
|
now designates set-and-expire in the settings as well.
|
|
|
|
|
|
2014-07-28 22:05:41 +08:00
|
|
|
|
* The ``sql*`` management commands now respect the ``allow_migrate()`` method
|
|
|
|
|
of :setting:`DATABASE_ROUTERS`. If you have models synced to non-default
|
|
|
|
|
databases, use the :djadminopt:`--database` flag to get SQL for those
|
|
|
|
|
models (previously they would always be included in the output).
|
|
|
|
|
|
2014-08-20 14:57:13 +08:00
|
|
|
|
* Decoding the query string from URLs now falls back to the ISO-8859-1 encoding
|
2014-07-13 01:37:59 +08:00
|
|
|
|
when the input is not valid UTF-8.
|
|
|
|
|
|
2014-09-06 04:19:03 +08:00
|
|
|
|
* With the addition of the
|
2015-09-03 08:50:34 +08:00
|
|
|
|
``django.contrib.auth.middleware.SessionAuthenticationMiddleware`` to
|
2014-12-03 20:33:44 +08:00
|
|
|
|
the default project template (pre-1.7.2 only), a database must be created
|
|
|
|
|
before accessing a page using :djadmin:`runserver`.
|
2014-09-06 04:19:03 +08:00
|
|
|
|
|
2014-02-03 21:09:27 +08:00
|
|
|
|
.. _deprecated-features-1.7:
|
|
|
|
|
|
2013-07-01 19:53:06 +08:00
|
|
|
|
Features deprecated in 1.7
|
|
|
|
|
==========================
|
|
|
|
|
|
2013-10-19 06:49:24 +08:00
|
|
|
|
``django.core.cache.get_cache``
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
2014-12-27 00:46:48 +08:00
|
|
|
|
``django.core.cache.get_cache`` has been supplanted by
|
2013-10-19 06:49:24 +08:00
|
|
|
|
:data:`django.core.cache.caches`.
|
|
|
|
|
|
2013-07-29 21:50:58 +08:00
|
|
|
|
``django.utils.dictconfig``/``django.utils.importlib``
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2013-07-02 04:50:58 +08:00
|
|
|
|
|
2013-07-29 21:50:58 +08:00
|
|
|
|
``django.utils.dictconfig`` and ``django.utils.importlib`` were copies of
|
|
|
|
|
respectively :mod:`logging.config` and :mod:`importlib` provided for Python
|
|
|
|
|
versions prior to 2.7. They have been deprecated.
|
2013-07-02 04:50:58 +08:00
|
|
|
|
|
2014-01-21 04:15:14 +08:00
|
|
|
|
``django.utils.module_loading.import_by_path``
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
2015-01-18 10:04:07 +08:00
|
|
|
|
The current ``django.utils.module_loading.import_by_path`` function
|
|
|
|
|
catches ``AttributeError``, ``ImportError``, and ``ValueError`` exceptions,
|
2014-01-21 04:15:14 +08:00
|
|
|
|
and re-raises :exc:`~django.core.exceptions.ImproperlyConfigured`. Such
|
|
|
|
|
exception masking makes it needlessly hard to diagnose circular import
|
|
|
|
|
problems, because it makes it look like the problem comes from inside Django.
|
|
|
|
|
It has been deprecated in favor of
|
|
|
|
|
:meth:`~django.utils.module_loading.import_string`.
|
|
|
|
|
|
2013-09-08 15:04:31 +08:00
|
|
|
|
``django.utils.tzinfo``
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
``django.utils.tzinfo`` provided two :class:`~datetime.tzinfo` subclasses,
|
|
|
|
|
``LocalTimezone`` and ``FixedOffset``. They've been deprecated in favor of
|
|
|
|
|
more correct alternatives provided by :mod:`django.utils.timezone`,
|
|
|
|
|
:func:`django.utils.timezone.get_default_timezone` and
|
|
|
|
|
:func:`django.utils.timezone.get_fixed_timezone`.
|
|
|
|
|
|
2013-07-01 19:53:06 +08:00
|
|
|
|
``django.utils.unittest``
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
``django.utils.unittest`` provided uniform access to the ``unittest2`` library
|
|
|
|
|
on all Python versions. Since ``unittest2`` became the standard library's
|
|
|
|
|
:mod:`unittest` module in Python 2.7, and Django 1.7 drops support for older
|
|
|
|
|
Python versions, this module isn't useful anymore. It has been deprecated. Use
|
|
|
|
|
:mod:`unittest` instead.
|
2013-07-16 21:10:04 +08:00
|
|
|
|
|
2013-08-03 13:41:15 +08:00
|
|
|
|
``django.utils.datastructures.SortedDict``
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
As :class:`~collections.OrderedDict` was added to the standard library in
|
2014-11-20 01:22:23 +08:00
|
|
|
|
Python 2.7, ``SortedDict`` is no longer needed and has been deprecated.
|
2013-08-03 13:41:15 +08:00
|
|
|
|
|
2015-03-18 01:41:11 +08:00
|
|
|
|
The two additional, deprecated methods provided by ``SortedDict`` (``insert()``
|
|
|
|
|
and ``value_for_index()``) have been removed. If you relied on these methods to
|
|
|
|
|
alter structures like form fields, you should now treat these ``OrderedDict``\s
|
|
|
|
|
as immutable objects and override them to change their content.
|
|
|
|
|
|
|
|
|
|
For example, you might want to override ``MyFormClass.base_fields`` (although
|
|
|
|
|
this attribute isn't considered a public API) to change the ordering of fields
|
|
|
|
|
for all ``MyFormClass`` instances; or similarly, you could override
|
|
|
|
|
``self.fields`` from inside ``MyFormClass.__init__()``, to change the fields
|
|
|
|
|
for a particular form instance. For example (from Django itself)::
|
|
|
|
|
|
|
|
|
|
PasswordChangeForm.base_fields = OrderedDict(
|
|
|
|
|
(k, PasswordChangeForm.base_fields[k])
|
|
|
|
|
for k in ['old_password', 'new_password1', 'new_password2']
|
|
|
|
|
)
|
|
|
|
|
|
2013-07-16 21:10:04 +08:00
|
|
|
|
Custom SQL location for models package
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Previously, if models were organized in a package (``myapp/models/``) rather
|
2014-12-27 02:56:08 +08:00
|
|
|
|
than simply ``myapp/models.py``, Django would look for initial SQL data in
|
|
|
|
|
``myapp/models/sql/``. This bug has been fixed so that Django
|
2014-12-31 00:50:50 +08:00
|
|
|
|
will search ``myapp/sql/`` as documented. After this issue was fixed, migrations
|
|
|
|
|
were added which deprecates initial SQL data. Thus, while this change still
|
|
|
|
|
exists, the deprecation is irrelevant as the entire feature will be removed in
|
|
|
|
|
Django 1.9.
|
2013-07-31 13:52:11 +08:00
|
|
|
|
|
2014-01-26 04:54:25 +08:00
|
|
|
|
Reorganization of ``django.contrib.sites``
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
``django.contrib.sites`` provides reduced functionality when it isn't in
|
|
|
|
|
:setting:`INSTALLED_APPS`. The app-loading refactor adds some constraints in
|
|
|
|
|
that situation. As a consequence, two objects were moved, and the old
|
|
|
|
|
locations are deprecated:
|
|
|
|
|
|
|
|
|
|
* :class:`~django.contrib.sites.requests.RequestSite` now lives in
|
|
|
|
|
``django.contrib.sites.requests``.
|
|
|
|
|
* :func:`~django.contrib.sites.shortcuts.get_current_site` now lives in
|
|
|
|
|
``django.contrib.sites.shortcuts``.
|
|
|
|
|
|
2013-09-04 09:01:45 +08:00
|
|
|
|
``declared_fieldsets`` attribute on ``ModelAdmin``
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2013-07-31 13:52:11 +08:00
|
|
|
|
|
2013-09-04 09:01:45 +08:00
|
|
|
|
``ModelAdmin.declared_fieldsets`` has been deprecated. Despite being a private
|
|
|
|
|
API, it will go through a regular deprecation path. This attribute was mostly
|
|
|
|
|
used by methods that bypassed ``ModelAdmin.get_fieldsets()`` but this was
|
|
|
|
|
considered a bug and has been addressed.
|
2013-08-11 03:00:12 +08:00
|
|
|
|
|
2014-01-22 14:43:33 +08:00
|
|
|
|
Reorganization of ``django.contrib.contenttypes``
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Since ``django.contrib.contenttypes.generic`` defined both admin and model
|
2015-03-16 14:05:43 +08:00
|
|
|
|
related objects, an import of this module could trigger unexpected side effects.
|
2014-01-22 14:43:33 +08:00
|
|
|
|
As a consequence, its contents were split into :mod:`~django.contrib.contenttypes`
|
|
|
|
|
submodules and the ``django.contrib.contenttypes.generic`` module is deprecated:
|
|
|
|
|
|
|
|
|
|
* :class:`~django.contrib.contenttypes.fields.GenericForeignKey` and
|
|
|
|
|
:class:`~django.contrib.contenttypes.fields.GenericRelation` now live in
|
|
|
|
|
:mod:`~django.contrib.contenttypes.fields`.
|
|
|
|
|
* :class:`~django.contrib.contenttypes.forms.BaseGenericInlineFormSet` and
|
|
|
|
|
:func:`~django.contrib.contenttypes.forms.generic_inlineformset_factory` now
|
|
|
|
|
live in :mod:`~django.contrib.contenttypes.forms`.
|
|
|
|
|
* :class:`~django.contrib.contenttypes.admin.GenericInlineModelAdmin`,
|
|
|
|
|
:class:`~django.contrib.contenttypes.admin.GenericStackedInline` and
|
|
|
|
|
:class:`~django.contrib.contenttypes.admin.GenericTabularInline` now live in
|
|
|
|
|
:mod:`~django.contrib.contenttypes.admin`.
|
|
|
|
|
|
2013-08-11 03:00:12 +08:00
|
|
|
|
``syncdb``
|
|
|
|
|
~~~~~~~~~~
|
|
|
|
|
|
2014-12-27 01:34:26 +08:00
|
|
|
|
The ``syncdb`` command has been deprecated in favor of the new :djadmin:`migrate`
|
2013-08-11 03:00:12 +08:00
|
|
|
|
command. ``migrate`` takes the same arguments as ``syncdb`` used to plus a few
|
|
|
|
|
more, so it's safe to just change the name you're calling and nothing else.
|
2013-09-17 00:52:05 +08:00
|
|
|
|
|
|
|
|
|
``util`` modules renamed to ``utils``
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
The following instances of ``util.py`` in the Django codebase have been renamed
|
|
|
|
|
to ``utils.py`` in an effort to unify all util and utils references:
|
|
|
|
|
|
|
|
|
|
* ``django.contrib.admin.util``
|
|
|
|
|
* ``django.contrib.gis.db.backends.util``
|
|
|
|
|
* ``django.db.backends.util``
|
|
|
|
|
* ``django.forms.util``
|
2013-09-04 09:01:45 +08:00
|
|
|
|
|
|
|
|
|
``get_formsets`` method on ``ModelAdmin``
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
``ModelAdmin.get_formsets`` has been deprecated in favor of the new
|
|
|
|
|
:meth:`~django.contrib.admin.ModelAdmin.get_formsets_with_inlines`, in order to
|
2014-05-11 10:13:50 +08:00
|
|
|
|
better handle the case of selectively showing inlines on a ``ModelAdmin``.
|
2013-09-28 16:22:46 +08:00
|
|
|
|
|
|
|
|
|
``IPAddressField``
|
|
|
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
2015-01-18 09:42:41 +08:00
|
|
|
|
The ``django.db.models.IPAddressField`` and ``django.forms.IPAddressField``
|
|
|
|
|
fields have been deprecated in favor of
|
2013-09-28 16:22:46 +08:00
|
|
|
|
:class:`django.db.models.GenericIPAddressField` and
|
|
|
|
|
:class:`django.forms.GenericIPAddressField`.
|
|
|
|
|
|
2013-09-24 00:40:19 +08:00
|
|
|
|
``BaseMemcachedCache._get_memcache_timeout`` method
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
The ``BaseMemcachedCache._get_memcache_timeout()`` method has been renamed to
|
|
|
|
|
``get_backend_timeout()``. Despite being a private API, it will go through the
|
|
|
|
|
normal deprecation.
|
2012-08-01 09:49:01 +08:00
|
|
|
|
|
|
|
|
|
Natural key serialization options
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
The ``--natural`` and ``-n`` options for :djadmin:`dumpdata` have been
|
|
|
|
|
deprecated. Use :djadminopt:`--natural-foreign` instead.
|
|
|
|
|
|
|
|
|
|
Similarly, the ``use_natural_keys`` argument for ``serializers.serialize()``
|
|
|
|
|
has been deprecated. Use ``use_natural_foreign_keys`` instead.
|
2013-10-16 04:36:49 +08:00
|
|
|
|
|
|
|
|
|
Merging of ``POST`` and ``GET`` arguments into ``WSGIRequest.REQUEST``
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
It was already strongly suggested that you use ``GET`` and ``POST`` instead of
|
|
|
|
|
``REQUEST``, because the former are more explicit. The property ``REQUEST`` is
|
|
|
|
|
deprecated and will be removed in Django 1.9.
|
|
|
|
|
|
|
|
|
|
``django.utils.datastructures.MergeDict`` class
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
``MergeDict`` exists primarily to support merging ``POST`` and ``GET``
|
|
|
|
|
arguments into a ``REQUEST`` property on ``WSGIRequest``. To merge
|
|
|
|
|
dictionaries, use ``dict.update()`` instead. The class ``MergeDict`` is
|
|
|
|
|
deprecated and will be removed in Django 1.9.
|
2013-11-05 01:31:34 +08:00
|
|
|
|
|
2013-11-11 16:05:17 +08:00
|
|
|
|
Language codes ``zh-cn``, ``zh-tw`` and ``fy-nl``
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
The currently used language codes for Simplified Chinese ``zh-cn``,
|
|
|
|
|
Traditional Chinese ``zh-tw`` and (Western) Frysian ``fy-nl`` are deprecated
|
|
|
|
|
and should be replaced by the language codes ``zh-hans``, ``zh-hant`` and
|
|
|
|
|
``fy`` respectively. If you use these language codes, you should rename the
|
|
|
|
|
locale directories and update your settings to reflect these changes. The
|
|
|
|
|
deprecated language codes will be removed in Django 1.9.
|
2013-11-02 04:15:41 +08:00
|
|
|
|
|
|
|
|
|
``django.utils.functional.memoize`` function
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
The function ``memoize`` is deprecated and should be replaced by the
|
|
|
|
|
``functools.lru_cache`` decorator (available from Python 3.2 onwards).
|
|
|
|
|
|
|
|
|
|
Django ships a backport of this decorator for older Python versions and it's
|
|
|
|
|
available at ``django.utils.lru_cache.lru_cache``. The deprecated function will
|
|
|
|
|
be removed in Django 1.9.
|
2013-12-08 02:28:01 +08:00
|
|
|
|
|
|
|
|
|
Geo Sitemaps
|
|
|
|
|
~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Google has retired support for the Geo Sitemaps format. Hence Django support
|
|
|
|
|
for Geo Sitemaps is deprecated and will be removed in Django 1.8.
|
2013-12-18 23:59:08 +08:00
|
|
|
|
|
|
|
|
|
Passing callable arguments to queryset methods
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Callable arguments for querysets were an undocumented feature that was
|
|
|
|
|
unreliable. It's been deprecated and will be removed in Django 1.9.
|
|
|
|
|
|
|
|
|
|
Callable arguments were evaluated when a queryset was constructed rather than
|
|
|
|
|
when it was evaluated, thus this feature didn't offer any benefit compared to
|
|
|
|
|
evaluating arguments before passing them to queryset and created confusion that
|
|
|
|
|
the arguments may have been evaluated at query time.
|
2013-11-05 17:16:27 +08:00
|
|
|
|
|
|
|
|
|
``ADMIN_FOR`` setting
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
The ``ADMIN_FOR`` feature, part of the admindocs, has been removed. You can
|
|
|
|
|
remove the setting from your configuration at your convenience.
|
2013-12-05 03:59:05 +08:00
|
|
|
|
|
|
|
|
|
``SplitDateTimeWidget`` with ``DateTimeField``
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
``SplitDateTimeWidget`` support in :class:`~django.forms.DateTimeField` is
|
|
|
|
|
deprecated, use ``SplitDateTimeWidget`` with
|
|
|
|
|
:class:`~django.forms.SplitDateTimeField` instead.
|
2014-01-20 10:45:21 +08:00
|
|
|
|
|
|
|
|
|
``validate``
|
|
|
|
|
~~~~~~~~~~~~
|
|
|
|
|
|
2015-01-18 08:00:12 +08:00
|
|
|
|
The ``validate`` management command is deprecated in favor of the
|
|
|
|
|
:djadmin:`check` command.
|
2014-01-20 10:45:21 +08:00
|
|
|
|
|
|
|
|
|
``django.core.management.BaseCommand``
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
``requires_model_validation`` is deprecated in favor of a new
|
|
|
|
|
``requires_system_checks`` flag. If the latter flag is missing, then the
|
|
|
|
|
value of the former flag is used. Defining both ``requires_system_checks`` and
|
|
|
|
|
``requires_model_validation`` results in an error.
|
|
|
|
|
|
|
|
|
|
The ``check()`` method has replaced the old ``validate()`` method.
|
|
|
|
|
|
2015-01-19 10:23:06 +08:00
|
|
|
|
``ModelAdmin`` validators
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
The ``ModelAdmin.validator_class`` and ``default_validator_class`` attributes
|
|
|
|
|
are deprecated in favor of the new ``checks_class`` attribute.
|
|
|
|
|
|
|
|
|
|
The ``ModelAdmin.validate()`` method is deprecated in favor of
|
|
|
|
|
``ModelAdmin.check()``.
|
2014-01-20 10:45:21 +08:00
|
|
|
|
|
2015-01-19 10:23:06 +08:00
|
|
|
|
The ``django.contrib.admin.validation`` module is deprecated.
|
2014-01-20 10:45:21 +08:00
|
|
|
|
|
|
|
|
|
``django.db.backends.DatabaseValidation.validate_field``
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
This method is deprecated in favor of a new ``check_field`` method.
|
|
|
|
|
The functionality required by ``check_field()`` is the same as that provided
|
|
|
|
|
by ``validate_field()``, but the output format is different. Third-party database
|
2014-11-14 01:01:22 +08:00
|
|
|
|
backends needing this functionality should provide an implementation of
|
|
|
|
|
``check_field()``.
|
2014-02-16 20:23:16 +08:00
|
|
|
|
|
|
|
|
|
Loading ``ssi`` and ``url`` template tags from ``future`` library
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Django 1.3 introduced ``{% load ssi from future %}`` and
|
|
|
|
|
``{% load url from future %}`` syntax for forward compatibility of the
|
2015-08-17 21:34:50 +08:00
|
|
|
|
``ssi`` and :ttag:`url` template tags. This syntax is now deprecated and
|
2014-02-16 20:23:16 +08:00
|
|
|
|
will be removed in Django 1.9. You can simply remove the
|
|
|
|
|
``{% load ... from future %}`` tags.
|
2014-02-21 21:46:23 +08:00
|
|
|
|
|
|
|
|
|
``django.utils.text.javascript_quote``
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
``javascript_quote()`` was an undocumented function present in ``django.utils.text``.
|
|
|
|
|
It was used internally in the :ref:`javascript_catalog view <javascript_catalog-view>`
|
|
|
|
|
whose implementation was changed to make use of ``json.dumps()`` instead.
|
|
|
|
|
If you were relying on this function to provide safe output from untrusted
|
|
|
|
|
strings, you should use ``django.utils.html.escapejs`` or the
|
|
|
|
|
:tfilter:`escapejs` template filter.
|
2015-05-01 03:39:29 +08:00
|
|
|
|
If all you need is to generate valid JavaScript strings, you can simply use
|
2014-02-21 21:46:23 +08:00
|
|
|
|
``json.dumps()``.
|
2014-03-01 17:42:08 +08:00
|
|
|
|
|
|
|
|
|
``fix_ampersands`` utils method and template filter
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
2014-03-22 01:22:39 +08:00
|
|
|
|
The ``django.utils.html.fix_ampersands`` method and the ``fix_ampersands``
|
2014-03-01 17:42:08 +08:00
|
|
|
|
template filter are deprecated, as the escaping of ampersands is already taken care
|
|
|
|
|
of by Django's standard HTML escaping features. Combining this with ``fix_ampersands``
|
|
|
|
|
would either result in double escaping, or, if the output is assumed to be safe,
|
|
|
|
|
a risk of introducing XSS vulnerabilities. Along with ``fix_ampersands``,
|
|
|
|
|
``django.utils.html.clean_html`` is deprecated, an undocumented function that calls
|
|
|
|
|
``fix_ampersands``.
|
|
|
|
|
As this is an accelerated deprecation, ``fix_ampersands`` and ``clean_html``
|
|
|
|
|
will be removed in Django 1.8.
|
2014-01-20 08:45:29 +08:00
|
|
|
|
|
|
|
|
|
Reorganization of database test settings
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2014-06-12 03:26:17 +08:00
|
|
|
|
|
2014-05-11 10:13:50 +08:00
|
|
|
|
All database settings with a ``TEST_`` prefix have been deprecated in favor of
|
2014-01-20 08:45:29 +08:00
|
|
|
|
entries in a :setting:`TEST <DATABASE-TEST>` dictionary in the database
|
2014-06-12 03:26:17 +08:00
|
|
|
|
settings. The old settings will be supported until Django 1.9. For backwards
|
|
|
|
|
compatibility with older versions of Django, you can define both versions of
|
|
|
|
|
the settings as long as they match.
|
2014-06-09 22:29:22 +08:00
|
|
|
|
|
|
|
|
|
FastCGI support
|
|
|
|
|
~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
FastCGI support via the ``runfcgi`` management command will be removed in
|
|
|
|
|
Django 1.9. Please deploy your project using WSGI.
|
2014-08-07 12:13:22 +08:00
|
|
|
|
|
2015-01-19 02:29:33 +08:00
|
|
|
|
Moved objects in ``contrib.sites``
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Following the app-loading refactor, two objects in
|
|
|
|
|
``django.contrib.sites.models`` needed to be moved because they must be
|
|
|
|
|
available without importing ``django.contrib.sites.models`` when
|
|
|
|
|
``django.contrib.sites`` isn't installed. Import ``RequestSite`` from
|
|
|
|
|
``django.contrib.sites.requests`` and ``get_current_site()`` from
|
|
|
|
|
``django.contrib.sites.shortcuts``. The old import locations will work until
|
|
|
|
|
Django 1.9.
|
|
|
|
|
|
2015-01-19 05:06:56 +08:00
|
|
|
|
``django.forms.forms.get_declared_fields()``
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Django no longer uses this functional internally. Even though it's a private
|
|
|
|
|
API, it'll go through the normal deprecation cycle.
|
|
|
|
|
|
2015-01-19 03:30:07 +08:00
|
|
|
|
Private Query Lookup APIs
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Private APIs ``django.db.models.sql.where.WhereNode.make_atom()`` and
|
|
|
|
|
``django.db.models.sql.where.Constraint`` are deprecated in favor of the new
|
|
|
|
|
:doc:`custom lookups API </ref/models/lookups>`.
|
|
|
|
|
|
2014-08-07 12:13:22 +08:00
|
|
|
|
.. removed-features-1.7:
|
|
|
|
|
|
|
|
|
|
Features removed in 1.7
|
|
|
|
|
=======================
|
|
|
|
|
|
|
|
|
|
These features have reached the end of their
|
|
|
|
|
:ref:`deprecation cycle <deprecation-removed-in-1.7>` and so have been
|
|
|
|
|
removed in Django 1.7 (please see the
|
|
|
|
|
:ref:`deprecation timeline <deprecation-removed-in-1.7>` for more details):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
* ``django.utils.simplejson`` is removed.
|
|
|
|
|
|
|
|
|
|
* ``django.utils.itercompat.product`` is removed.
|
|
|
|
|
|
|
|
|
|
* INSTALLED_APPS and TEMPLATE_DIRS are no longer corrected from a plain
|
|
|
|
|
string into a tuple.
|
|
|
|
|
|
|
|
|
|
* :class:`~django.http.HttpResponse`,
|
|
|
|
|
:class:`~django.template.response.SimpleTemplateResponse`,
|
|
|
|
|
:class:`~django.template.response.TemplateResponse`,
|
|
|
|
|
:func:`~django.shortcuts.render_to_response`,
|
|
|
|
|
:func:`~django.contrib.sitemaps.views.index`, and
|
|
|
|
|
:func:`~django.contrib.sitemaps.views.sitemap` no longer take a ``mimetype``
|
|
|
|
|
argument
|
|
|
|
|
|
|
|
|
|
* :class:`~django.http.HttpResponse` immediately consumes its content if it's
|
|
|
|
|
an iterator.
|
|
|
|
|
|
|
|
|
|
* The ``AUTH_PROFILE_MODULE`` setting, and the ``get_profile()`` method on
|
|
|
|
|
the User model are removed.
|
|
|
|
|
|
|
|
|
|
* The ``cleanup`` management command is removed.
|
|
|
|
|
|
|
|
|
|
* The ``daily_cleanup.py`` script is removed.
|
|
|
|
|
|
|
|
|
|
* :meth:`~django.db.models.query.QuerySet.select_related` no longer has a
|
|
|
|
|
``depth`` keyword argument.
|
|
|
|
|
|
|
|
|
|
* The ``get_warnings_state()``/``restore_warnings_state()``
|
|
|
|
|
functions from :mod:`django.test.utils` and the ``save_warnings_state()``/
|
|
|
|
|
``restore_warnings_state()``
|
|
|
|
|
:ref:`django.test.*TestCase <django-testcase-subclasses>` are removed.
|
|
|
|
|
|
|
|
|
|
* The ``check_for_test_cookie`` method in
|
|
|
|
|
:class:`~django.contrib.auth.forms.AuthenticationForm` is removed.
|
|
|
|
|
|
|
|
|
|
* The version of :func:`django.contrib.auth.views.password_reset_confirm` that
|
|
|
|
|
supports base36 encoded user IDs
|
|
|
|
|
(``django.contrib.auth.views.password_reset_confirm_uidb36``) is removed.
|
|
|
|
|
|
|
|
|
|
* The ``django.utils.encoding.StrAndUnicode`` mix-in is removed.
|