django/docs/releases/1.8.txt

377 lines
12 KiB
Plaintext
Raw Normal View History

2014-03-21 10:19:19 +00:00
============================================
Django 1.8 release notes - UNDER DEVELOPMENT
============================================
Welcome to Django 1.8!
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
1.6 or older versions. We've also dropped some features, which are detailed in
:ref:`our deprecation plan <deprecation-removed-in-1.8>`, and we've `begun the
deprecation process for some features`_.
.. _`new features`: `What's new in Django 1.8`_
.. _`backwards incompatible changes`: `Backwards incompatible changes in 1.8`_
.. _`begun the deprecation process for some features`: `Features deprecated in 1.8`_
Python compatibility
====================
Like Django 1.7, Django 1.8 requires Python 2.7 or above, though we
**highly recommend** the latest minor release.
What's new in Django 1.8
========================
...
Minor features
~~~~~~~~~~~~~~
:mod:`django.contrib.admin`
^^^^^^^^^^^^^^^^^^^^^^^^^^^
* ...
:mod:`django.contrib.auth`
^^^^^^^^^^^^^^^^^^^^^^^^^^
* Authorization backends can now raise
:class:`~django.core.exceptions.PermissionDenied` in
:meth:`~django.contrib.auth.models.User.has_perm`
and :meth:`~django.contrib.auth.models.User.has_module_perms`
to short-circuit permission checking.
2014-03-21 10:19:19 +00:00
:mod:`django.contrib.formtools`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* A :doc:`form wizard </ref/contrib/formtools/form-wizard>` using the
:class:`~django.contrib.formtools.wizard.views.CookieWizardView` will now ignore
an invalid cookie, and the wizard will restart from the first step. An invalid
cookie can occur in cases of intentional manipulation, but also after a secret
key change. Previously, this would raise ``WizardViewCookieModified``, a
``SuspiciousOperation``, causing an exception for any user with an invalid cookie
upon every request to the wizard, until the cookie is removed.
2014-03-21 10:19:19 +00:00
:mod:`django.contrib.gis`
^^^^^^^^^^^^^^^^^^^^^^^^^^
* Compatibility shims for ``SpatialRefSys`` and ``GeometryColumns`` changed in
Django 1.2 have been removed.
2014-03-21 10:19:19 +00:00
:mod:`django.contrib.messages`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* ...
:mod:`django.contrib.redirects`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* ...
:mod:`django.contrib.sessions`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* Session cookie is now deleted after
:meth:`~django.contrib.sessions.backends.base.SessionBase.flush()` is called.
2014-03-21 10:19:19 +00:00
:mod:`django.contrib.sitemaps`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* ...
:mod:`django.contrib.sites`
^^^^^^^^^^^^^^^^^^^^^^^^^^^
* ...
:mod:`django.contrib.staticfiles`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* ...
:mod:`django.contrib.syndication`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* ...
Cache
^^^^^
* ...
Email
^^^^^
* :ref:`Email backends <topic-email-backends>` now support the context manager
protocol for opening and closing connections.
2014-03-21 10:19:19 +00:00
File Storage
^^^^^^^^^^^^
* ...
File Uploads
^^^^^^^^^^^^
* ...
Forms
^^^^^
* Form widgets now render attributes with a value of ``True`` or ``False``
as HTML5 boolean attributes.
2014-03-21 10:19:19 +00:00
* The new :meth:`~django.forms.Form.has_error()` method allows checking
if a specific error has happened.
* If :attr:`~django.forms.Form.required_css_class` is defined on a form, then
the ``<label>`` tags for required fields will have this class present in its
attributes.
* The rendering of non-field errors in unordered lists (``<ul>``) now includes
``nonfield`` in its list of classes to distinguish them from field-specific
errors.
* :class:`~django.forms.Field` now accepts a
:attr:`~django.forms.Field.label_suffix` argument, which will override the
form's :attr:`~django.forms.Form.label_suffix`. This enables customizing the
suffix on a per-field basis — previously it wasn't possible to override
a form's :attr:`~django.forms.Form.label_suffix` while using shortcuts such
as ``{{ form.as_p }}`` in templates.
* :class:`~django.forms.extras.widgets.SelectDateWidget` now accepts an
:attr:`~django.forms.extras.widgets.SelectDateWidget.empty_label` argument, which will
override the top list choice label when :class:`~django.forms.DateField` is not required.
2014-03-21 10:19:19 +00:00
Internationalization
^^^^^^^^^^^^^^^^^^^^
* :setting:`FORMAT_MODULE_PATH` can now be a list of strings representing
module paths. This allows importing several format modules from different
reusable apps. It also allows overriding those custom formats in your main
Django project.
2014-03-21 10:19:19 +00:00
Management Commands
^^^^^^^^^^^^^^^^^^^
2014-03-25 13:43:51 +00:00
* :djadmin:`dumpdata` now has the option :djadminopt:`--output` which allows
specifying the file to which the serialized data is written.
2014-03-21 10:19:19 +00:00
* :djadmin:`makemessages` and :djadmin:`compilemessages` now have the option
:djadminopt:`--exclude` which allows exclusion of specific locales from
processing.
* The :djadminopt:`--ignorenonexistent` option of the :djadmin:`loaddata`
management command now ignores data for models that no longer exist.
* :djadmin:`runserver` now uses daemon threads for faster reloading.
2014-03-21 10:19:19 +00:00
Models
^^^^^^
* ...
Signals
^^^^^^^
* Exceptions from the ``(receiver, exception)`` tuples returned by
:meth:`Signal.send_robust() <django.dispatch.Signal.send_robust>` now have
their traceback attached as a ``__traceback__`` attribute.
2014-03-21 10:19:19 +00:00
Templates
^^^^^^^^^
* ...
Requests and Responses
^^^^^^^^^^^^^^^^^^^^^^
* ...
Tests
^^^^^
* The ``count`` argument was added to
:meth:`~django.test.SimpleTestCase.assertTemplateUsed`. This allows you to
assert that a template was rendered a specific number of times.
2014-03-21 10:19:19 +00:00
* The new :meth:`~django.test.SimpleTestCase.assertJSONNotEqual` assertion
allows you to test that two JSON fragments are not equal.
* Added the ability to preserve the test database by adding the :djadminopt:`--keepdb`
flag.
2014-03-21 10:19:19 +00:00
Validators
^^^^^^^^^^
* ...
Backwards incompatible changes in 1.8
=====================================
.. warning::
In addition to the changes outlined in this section, be sure to review the
:ref:`deprecation plan <deprecation-removed-in-1.8>` for any features that
2014-03-21 10:19:19 +00: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.
Related object operations are run in a transaction
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Some operations on related objects such as
:meth:`~django.db.models.fields.related.RelatedManager.add()` or
:ref:`direct assignment<direct-assignment>` ran multiple data modifying
queries without wrapping them in transactions. To reduce the risk of data
corruption, all data modifying methods that affect multiple related objects
(i.e. ``add()``, ``remove()``, ``clear()``, and :ref:`direct assignment
<direct-assignment>`) now perform their data modifying queries from within a
transaction, provided your database supports transactions.
This has one backwards incompatible side effect, signal handlers triggered from
these methods are now executed within the method's transaction and any
exception in a signal handler will prevent the whole operation.
Unassigning unsaved objects to relations raises an error
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Assigning unsaved objects to a :class:`~django.db.models.ForeignKey`,
:class:`~django.contrib.contenttypes.fields.GenericForeignKey`, and
:class:`~django.db.models.OneToOneField` now raises a :exc:`ValueError`.
Previously, the assignment of an unsaved object would be silently ignored.
For example::
>>> book = Book.objects.create(name="Django")
>>> book.author = Author(name="John")
>>> book.author.save()
>>> book.save()
>>> Book.objects.get(name="Django")
>>> book.author
>>>
Now, an error will be raised to prevent data loss::
>>> book.author = Author(name="john")
Traceback (most recent call last):
...
ValueError: Cannot assign "<Author: John>": "Author" instance isn't saved in the database.
2014-03-21 10:19:19 +00:00
Miscellaneous
~~~~~~~~~~~~~
* ``URLField.to_python`` no longer adds a trailing slash to pathless URLs.
2014-03-21 10:19:19 +00:00
2014-03-27 22:02:28 +00:00
* ``django.contrib.gis`` dropped support for GEOS 3.1 and GDAL 1.6.
2014-03-27 21:53:04 +00:00
* The :tfilter:`length` template filter now returns ``0`` for an undefined
variable, rather than an empty string.
2014-03-21 10:19:19 +00:00
.. _deprecated-features-1.8:
Features deprecated in 1.8
==========================
Loading ``cycle`` and ``firstof`` template tags from ``future`` library
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Django 1.6 introduced ``{% load cycle from future %}`` and
``{% load firstof from future %}`` syntax for forward compatibility of the
:ttag:`cycle` and :ttag:`firstof` template tags. This syntax is now deprecated
and will be removed in Django 2.0. You can simply remove the
``{% load ... from future %}`` tags.
``django.conf.urls.patterns()``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In the olden days of Django, it was encouraged to reference views as strings
in ``urlpatterns``::
urlpatterns = patterns('',
url('^$', 'myapp.views.myview'),
)
and Django would magically import ``myapp.views.myview`` internally and turn
the string into a real function reference. In order to reduce repetition when
referencing many views from the same module, the ``patterns()`` function takes
a required initial ``prefix`` argument which is prepended to all
views-as-strings in that set of ``urlpatterns``::
urlpatterns = patterns('myapp.views',
url('^$', 'myview'),
url('^other/$', 'otherview'),
)
In the modern era, we have updated the tutorial to instead recommend importing
your views module and referencing your view functions (or classes) directly.
This has a number of advantages, all deriving from the fact that we are using
normal Python in place of "Django String Magic": the errors when you mistype a
view name are less obscure, IDEs can help with autocompletion of view names,
etc.
So these days, the above use of the ``prefix`` arg is much more likely to be
written (and is better written) as::
from myapp import views
urlpatterns = patterns('',
url('^$', views.myview),
url('^other/$', views.otherview),
)
Thus ``patterns()`` serves little purpose and is a burden when teaching new users
(answering the newbie's question "why do I need this empty string as the first
argument to ``patterns()``?"). For these reasons, we are deprecating it.
2014-04-03 13:05:31 +00:00
Updating your code is as simple as ensuring that ``urlpatterns`` is a list of
:func:`django.conf.urls.url` instances. For example::
from django.conf.urls import url
from myapp import views
urlpatterns = [
url('^$', views.myview),
url('^other/$', views.otherview),
]
``django.test.SimpleTestCase.urls``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The attribute :attr:`SimpleTestCase.urls <django.test.SimpleTestCase.urls>`
for specifying URLconf configuration in tests has been deprecated and will be
removed in Django 2.0. Use :func:`@override_settings(ROOT_URLCONF=...)
<django.test.override_settings>` instead.
``prefix`` argument to :func:`~django.conf.urls.i18n.i18n_patterns`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Related to the previous item, the ``prefix`` argument to
:func:`django.conf.urls.i18n.i18n_patterns` has been deprecated. Simply pass a
list of :func:`django.conf.urls.url` instances instead.
Using an incorrect count of unpacked values in the :ttag:`for` template tag
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Using an incorrect count of unpacked values in :ttag:`for` tag will raise an
exception rather than fail silently in Django 2.0.
Passing a dotted path to :func:`~django.core.urlresolvers.reverse()` and :ttag:`url`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Reversing URLs by Python path is an expensive operation as it causes the
path being reversed to be imported. This behavior has also resulted in a
`security issue`_. Use :ref:`named URL patterns <naming-url-patterns>`
for reversing instead.
If you are using :mod:`django.contrib.sitemaps`, add the ``name`` argument to
2014-06-05 10:31:04 +00:00
the ``url`` that references :func:`django.contrib.sitemaps.views.sitemap`::
url(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap',
{'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.sitemap')
to ensure compatibility when reversing by Python path is removed in Django 2.0.
.. _security issue: https://www.djangoproject.com/weblog/2014/apr/21/security/#s-issue-unexpected-code-execution-using-reverse