mirror of
https://github.com/django/django.git
synced 2024-12-25 10:35:48 +00:00
517 lines
18 KiB
Plaintext
517 lines
18 KiB
Plaintext
=============================================
|
||
Django 1.11 release notes - UNDER DEVELOPMENT
|
||
=============================================
|
||
|
||
Welcome to Django 1.11!
|
||
|
||
These release notes cover the :ref:`new features <whats-new-1.11>`, as well as
|
||
some :ref:`backwards incompatible changes <backwards-incompatible-1.11>` you'll
|
||
want to be aware of when upgrading from Django 1.10 or older versions. We've
|
||
:ref:`begun the deprecation process for some features
|
||
<deprecated-features-1.11>`.
|
||
|
||
See the :doc:`/howto/upgrade-version` guide if you're updating an existing
|
||
project.
|
||
|
||
Django 1.11 is designated as a :term:`long-term support release`. It will
|
||
receive security updates for at least three years after its release. Support
|
||
for the previous LTS, Django 1.8, will end in April 2018.
|
||
|
||
Python compatibility
|
||
====================
|
||
|
||
Like Django 1.10, Django 1.11 requires Python 2.7, 3.4, or 3.5. We **highly
|
||
recommend** and only officially support the latest release of each series.
|
||
|
||
The Django 1.11.x series is the last to support Python 2. The next major
|
||
release, Django 2.0, will only support Python 3.5+.
|
||
|
||
Deprecating warnings are no longer loud by default
|
||
==================================================
|
||
|
||
Unlike older versions of Django, Django's own deprecation warnings are no
|
||
longer displayed by default. This is consistent with Python's default behavior.
|
||
|
||
This change allows third-party apps to support both Django 1.11 LTS and Django
|
||
1.8 LTS without having to add code to avoid deprecation warnings.
|
||
|
||
Following the release of Django 2.0, we suggest that third-party app authors
|
||
drop support for all versions of Django prior to 1.11. At that time, you should
|
||
be able run your package's tests using ``python -Wd`` so that deprecation
|
||
warnings do appear. After making the deprecation warning fixes, your app should
|
||
be compatible with Django 2.0.
|
||
|
||
.. _whats-new-1.11:
|
||
|
||
What's new in Django 1.11
|
||
=========================
|
||
|
||
Class-based model indexes
|
||
-------------------------
|
||
|
||
The new :mod:`django.db.models.indexes` module contains classes which ease
|
||
creating database indexes. Indexes are added to models using the
|
||
:attr:`Meta.indexes <django.db.models.Options.indexes>` option.
|
||
|
||
The :class:`~django.db.models.Index` class creates a b-tree index, as if you
|
||
used :attr:`~django.db.models.Field.db_index` on the model field or
|
||
:attr:`~django.db.models.Options.index_together` on the model ``Meta`` class.
|
||
It can be subclassed to support different index types, such as
|
||
:class:`~django.contrib.postgres.indexes.GinIndex`. It also allows defining the
|
||
order (ASC/DESC) for the columns of the index.
|
||
|
||
Minor features
|
||
--------------
|
||
|
||
:mod:`django.contrib.admin`
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
* :attr:`.ModelAdmin.date_hierarchy` can now reference fields across relations.
|
||
|
||
:mod:`django.contrib.admindocs`
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
* ...
|
||
|
||
:mod:`django.contrib.auth`
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
* The default iteration count for the PBKDF2 password hasher is increased by
|
||
20%.
|
||
|
||
* The :class:`~django.contrib.auth.views.LoginView` and
|
||
:class:`~django.contrib.auth.views.LogoutView` class-based views supersede the
|
||
deprecated ``login()`` and ``logout()`` function-based views.
|
||
|
||
* The :class:`~django.contrib.auth.views.PasswordChangeView`,
|
||
:class:`~django.contrib.auth.views.PasswordChangeDoneView`,
|
||
:class:`~django.contrib.auth.views.PasswordResetView`,
|
||
:class:`~django.contrib.auth.views.PasswordResetDoneView`,
|
||
:class:`~django.contrib.auth.views.PasswordResetConfirmView`, and
|
||
:class:`~django.contrib.auth.views.PasswordResetCompleteView` class-based
|
||
views supersede the deprecated ``password_change()``,
|
||
``password_change_done()``, ``password_reset()``, ``password_reset_done()``,
|
||
``password_reset_confirm()``, and ``password_reset_complete()`` function-based
|
||
views.
|
||
|
||
* The new ``post_reset_login`` attribute for
|
||
:class:`~django.contrib.auth.views.PasswordResetConfirmView` allows
|
||
automatically logging in a user after a successful password reset.
|
||
|
||
* :func:`~django.contrib.auth.update_session_auth_hash` now rotates the session
|
||
key to allow a password change to invalidate stolen session cookies.
|
||
|
||
:mod:`django.contrib.contenttypes`
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
* When stale content types are detected after the ``migrate`` command, there's
|
||
now a list of related objects such as ``auth.Permission``\s that will also be
|
||
deleted. Previously, only the content types were listed.
|
||
|
||
:mod:`django.contrib.gis`
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
* The new :meth:`.GEOSGeometry.from_gml` and :meth:`.OGRGeometry.from_gml`
|
||
methods allow creating geometries from GML.
|
||
|
||
* Added support for the :lookup:`dwithin` lookup on SpatiaLite.
|
||
|
||
* The OpenLayers-based form widgets now use ``OpenLayers.js`` from
|
||
``https://cdnjs.cloudflare.com`` which is more suitable for production use
|
||
than the the old ``http://openlayers.org`` source.
|
||
|
||
:mod:`django.contrib.messages`
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
* ...
|
||
|
||
:mod:`django.contrib.postgres`
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
* The new ``distinct`` argument for
|
||
:class:`~django.contrib.postgres.aggregates.StringAgg` determines if
|
||
concatenated values will be distinct.
|
||
|
||
* The new :class:`~django.contrib.postgres.indexes.GinIndex` class allows
|
||
creating gin indexes in the database.
|
||
|
||
* :class:`~django.contrib.postgres.fields.JSONField` accepts a new ``encoder``
|
||
parameter to specify a custom class to encode data types not supported by the
|
||
standard encoder.
|
||
|
||
:mod:`django.contrib.redirects`
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
* ...
|
||
|
||
:mod:`django.contrib.sessions`
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
* ...
|
||
|
||
:mod:`django.contrib.sitemaps`
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
* ...
|
||
|
||
:mod:`django.contrib.sites`
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
* ...
|
||
|
||
:mod:`django.contrib.staticfiles`
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
* ...
|
||
|
||
:mod:`django.contrib.syndication`
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
* ...
|
||
|
||
Cache
|
||
~~~~~
|
||
|
||
* Memcached backends now pass the contents of :setting:`OPTIONS <CACHES-OPTIONS>`
|
||
as keyword arguments to the client constructors, allowing for more advanced
|
||
control of client behavior. See the :ref:`cache arguments <cache_arguments>`
|
||
documentation for examples.
|
||
|
||
* Memcached backends now allow defining multiple servers as a comma-delimited
|
||
string in :setting:`LOCATION <CACHES-LOCATION>`, for convenience with
|
||
third-party services that use such strings in environment variables.
|
||
|
||
CSRF
|
||
~~~~
|
||
|
||
* ...
|
||
|
||
Database backends
|
||
~~~~~~~~~~~~~~~~~
|
||
|
||
* Added the ``skip_locked`` argument to :meth:`.QuerySet.select_for_update()`
|
||
on PostgreSQL 9.5+ and Oracle to execute queries with
|
||
``FOR UPDATE SKIP LOCKED``.
|
||
|
||
* Added the :setting:`TEST['TEMPLATE'] <TEST_TEMPLATE>` setting to let
|
||
PostgreSQL users specify a template for creating the test database.
|
||
|
||
Email
|
||
~~~~~
|
||
|
||
* Added the :setting:`EMAIL_USE_LOCALTIME` setting to allow sending SMTP date
|
||
headers in the local time zone rather than in UTC.
|
||
|
||
* ``EmailMessage.attach()`` and ``attach_file()`` now fall back to MIME type
|
||
``application/octet-stream`` when binary content that can't be decoded as
|
||
UTF-8 is specified for a ``text/*`` attachment.
|
||
|
||
File Storage
|
||
~~~~~~~~~~~~
|
||
|
||
* To make it wrappable by :class:`io.TextIOWrapper`,
|
||
:class:`~django.core.files.File` now has the ``readable()``, ``writable()``,
|
||
and ``seekable()`` methods.
|
||
|
||
File Uploads
|
||
~~~~~~~~~~~~
|
||
|
||
* ...
|
||
|
||
Forms
|
||
~~~~~
|
||
|
||
* The new :attr:`CharField.empty_value <django.forms.CharField.empty_value>`
|
||
attribute allows specifying the Python value to use to represent "empty".
|
||
|
||
* The new :meth:`Form.get_initial_for_field()
|
||
<django.forms.Form.get_initial_for_field>` method returns initial data for a
|
||
form field.
|
||
|
||
Generic Views
|
||
~~~~~~~~~~~~~
|
||
|
||
* ...
|
||
|
||
Internationalization
|
||
~~~~~~~~~~~~~~~~~~~~
|
||
|
||
* Number formatting and the :setting:`NUMBER_GROUPING` setting support
|
||
non-uniform digit grouping.
|
||
|
||
Management Commands
|
||
~~~~~~~~~~~~~~~~~~~
|
||
|
||
* The new :option:`loaddata --exclude` option allows excluding models and apps
|
||
while loading data from fixtures.
|
||
|
||
Migrations
|
||
~~~~~~~~~~
|
||
|
||
* ...
|
||
|
||
Models
|
||
~~~~~~
|
||
|
||
* Added support for callable values in the ``defaults`` argument of
|
||
:meth:`QuerySet.update_or_create()
|
||
<django.db.models.query.QuerySet.update_or_create>` and
|
||
:meth:`~django.db.models.query.QuerySet.get_or_create`.
|
||
|
||
* :class:`~django.db.models.ImageField` now has a default
|
||
:data:`~django.core.validators.validate_image_file_extension` validator.
|
||
|
||
* Added support for time truncation to
|
||
:class:`~django.db.models.functions.datetime.Trunc` functions.
|
||
|
||
* Added the :class:`~django.db.models.functions.datetime.TruncTime` function
|
||
to truncate :class:`~django.db.models.DateTimeField` to its time component
|
||
and exposed it through the :lookup:`time` lookup.
|
||
|
||
* Added support for expressions in :meth:`.QuerySet.values` and
|
||
:meth:`~.QuerySet.values_list`.
|
||
|
||
* Added support for query expressions on lookups that take multiple arguments,
|
||
such as ``range``.
|
||
|
||
Requests and Responses
|
||
~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
* Added :meth:`QueryDict.fromkeys() <django.http.QueryDict.fromkeys>`.
|
||
|
||
* :class:`~django.middleware.common.CommonMiddleware` now sets the
|
||
``Content-Length`` response header for non-streaming responses.
|
||
|
||
* Added the :setting:`SECURE_HSTS_PRELOAD` setting to allow appending the
|
||
``preload`` directive to the ``Strict-Transport-Security`` header.
|
||
|
||
Serialization
|
||
~~~~~~~~~~~~~
|
||
|
||
* The new ``django.core.serializers.base.Serializer.stream_class`` attribute
|
||
allows subclasses to customize the default stream.
|
||
|
||
* The encoder used by the :ref:`JSON serializer <serialization-formats-json>`
|
||
can now be customized by passing a ``cls`` keyword argument to the
|
||
``serializers.serialize()`` function.
|
||
|
||
* :class:`~django.core.serializers.json.DjangoJSONEncoder` now serializes
|
||
:class:`~datetime.timedelta` objects (used by
|
||
:class:`~django.db.models.DurationField`).
|
||
|
||
Signals
|
||
~~~~~~~
|
||
|
||
* ...
|
||
|
||
Templates
|
||
~~~~~~~~~
|
||
|
||
* :meth:`~django.utils.safestring.mark_safe` can now be used as a decorator.
|
||
|
||
* The :class:`~django.template.backends.jinja2.Jinja2` template backend now
|
||
supports context processors by setting the ``'context_processors'`` option in
|
||
:setting:`OPTIONS <TEMPLATES-OPTIONS>`.
|
||
|
||
* The :ttag:`regroup` tag now returns ``namedtuple``\s instead of dictionaries
|
||
so you can unpack the group object directly in a loop, e.g.
|
||
``{% for grouper, list in regrouped %}``.
|
||
|
||
* Added a :ttag:`resetcycle` template tag to allow resetting the sequence of
|
||
the :ttag:`cycle` template tag.
|
||
|
||
Tests
|
||
~~~~~
|
||
|
||
* Added :meth:`.DiscoverRunner.get_test_runner_kwargs` to allow customizing the
|
||
keyword arguments passed to the test runner.
|
||
|
||
* Added the :option:`test --debug-mode` option to help troubleshoot test
|
||
failures by setting the :setting:`DEBUG` setting to ``True``.
|
||
|
||
* The new :func:`django.test.utils.setup_databases` (moved from
|
||
``django.test.runner``) and :func:`~django.test.utils.teardown_databases`
|
||
functions make it easier to build custom test runners.
|
||
|
||
* Added support for :meth:`python:unittest.TestCase.subTest`’s when using the
|
||
:option:`test --parallel` option.
|
||
|
||
URLs
|
||
~~~~
|
||
|
||
* ...
|
||
|
||
Validators
|
||
~~~~~~~~~~
|
||
|
||
* Added :class:`~django.core.validators.FileExtensionValidator` to validate
|
||
file extensions and
|
||
:data:`~django.core.validators.validate_image_file_extension` to validate
|
||
image files.
|
||
|
||
.. _backwards-incompatible-1.11:
|
||
|
||
Backwards incompatible changes in 1.11
|
||
======================================
|
||
|
||
:mod:`django.contrib.gis`
|
||
-------------------------
|
||
|
||
* To simplify the codebase and because it's easier to install than when
|
||
``contrib.gis`` was first released, :ref:`gdalbuild` is now a required
|
||
dependency for GeoDjango. In older versions, it's only required for SQLite.
|
||
|
||
Database backend API
|
||
--------------------
|
||
|
||
* The ``DatabaseOperations.time_trunc_sql()`` method is added to support
|
||
``TimeField`` truncation. It accepts a ``lookup_type`` and ``field_name``
|
||
arguments and returns the appropriate SQL to truncate the given time field
|
||
``field_name`` to a time object with only the given specificity. The
|
||
``lookup_type`` argument can be either ``'hour'``, ``'minute'``, or
|
||
``'second'``.
|
||
|
||
* The ``DatabaseOperations.datetime_cast_time_sql()`` method is added to
|
||
support the :lookup:`time` lookup. It accepts a ``field_name`` and ``tzname``
|
||
arguments and returns the SQL necessary to cast a datetime value to time value.
|
||
|
||
* To enable ``FOR UPDATE SKIP LOCKED`` support, set
|
||
``DatabaseFeatures.has_select_for_update_skip_locked = True``.
|
||
|
||
* The new ``DatabaseFeatures.supports_index_column_ordering`` attribute
|
||
specifies if a database allows defining ordering for columns in indexes. The
|
||
default value is ``True`` and the ``DatabaseIntrospection.get_constraints()``
|
||
method should include an ``'orders'`` key in each of the returned
|
||
dictionaries with a list of ``'ASC'`` and/or ``'DESC'`` values corresponding
|
||
to the the ordering of each column in the index.
|
||
|
||
Dropped support for PostgreSQL 9.2 and PostGIS 2.0
|
||
--------------------------------------------------
|
||
|
||
Upstream support for PostgreSQL 9.2 ends in September 2017. As a consequence,
|
||
Django 1.11 sets PostgreSQL 9.3 as the minimum version it officially supports.
|
||
|
||
Support for PostGIS 2.0 is also removed as PostgreSQL 9.2 is the last version
|
||
to support it.
|
||
|
||
``LiveServerTestCase`` binds to port zero
|
||
-----------------------------------------
|
||
|
||
Rather than taking a port range and iterating to find a free port,
|
||
``LiveServerTestCase`` binds to port zero and relies on the operating system
|
||
to assign a free port. The ``DJANGO_LIVE_TEST_SERVER_ADDRESS`` environment
|
||
variable is no longer used, and as it's also no longer used, the
|
||
``manage.py test --liveserver`` option is removed.
|
||
|
||
Protection against insecure redirects in :mod:`django.contrib.auth` and ``i18n`` views
|
||
--------------------------------------------------------------------------------------
|
||
|
||
``LoginView``, ``LogoutView`` (and the deprecated function-based equivalents),
|
||
and :func:`~django.views.i18n.set_language` protect users from being redirected
|
||
to non-HTTPS ``next`` URLs when the app is running over HTTPS.
|
||
|
||
Miscellaneous
|
||
-------------
|
||
|
||
* If no items in the feed have a ``pubdate`` or ``updateddate`` attribute,
|
||
:meth:`SyndicationFeed.latest_post_date()
|
||
<django.utils.feedgenerator.SyndicationFeed.latest_post_date>` now returns
|
||
the current UTC date/time, instead of a datetime without any timezone
|
||
information.
|
||
|
||
* Support for SpatiaLite < 4.0 is dropped.
|
||
|
||
* CSRF failures are logged to the ``django.security.csrf`` logger instead of
|
||
``django.request``.
|
||
|
||
* :setting:`ALLOWED_HOSTS` validation is no longer disabled when running tests.
|
||
If your application includes tests with custom host names, you must include
|
||
those host names in :setting:`ALLOWED_HOSTS`. See
|
||
:ref:`topics-testing-advanced-multiple-hosts`.
|
||
|
||
* Using a foreign key's id (e.g. ``'field_id'``) in ``ModelAdmin.list_display``
|
||
displays the related object's ID. Remove the ``_id`` suffix if you want the
|
||
old behavior of the string representation of the object.
|
||
|
||
* In model forms, :class:`~django.db.models.CharField` with ``null=True`` now
|
||
saves ``NULL`` for blank values instead of empty strings.
|
||
|
||
* On Oracle, :meth:`Model.validate_unique()
|
||
<django.db.models.Model.validate_unique>` no longer checks empty strings for
|
||
uniqueness as the database interprets the value as ``NULL``.
|
||
|
||
* If you subclass :class:`.AbstractUser` and override ``clean()``, be sure it
|
||
calls ``super()``. :meth:`.BaseUserManager.normalize_email` is called in a
|
||
new :meth:`.AbstractUser.clean` method so that normalization is applied in
|
||
cases like model form validation.
|
||
|
||
* ``EmailField`` and ``URLField`` no longer accept the ``strip`` keyword
|
||
argument. Remove it because it doesn't have an effect in older versions of
|
||
Django as these fields alway strip whitespace.
|
||
|
||
* The ``checked`` attribute rendered by form widgets now uses HTML5 boolean
|
||
syntax rather than XHTML's ``checked='checked'``.
|
||
|
||
* :meth:`RelatedManager.add()
|
||
<django.db.models.fields.related.RelatedManager.add>`,
|
||
:meth:`~django.db.models.fields.related.RelatedManager.remove`,
|
||
:meth:`~django.db.models.fields.related.RelatedManager.clear`, and
|
||
:meth:`~django.db.models.fields.related.RelatedManager.set` now
|
||
clear the ``prefetch_related()`` cache.
|
||
|
||
* To prevent possible loss of saved settings,
|
||
:func:`~django.test.utils.setup_test_environment` now raises an exception if
|
||
called a second time before calling
|
||
:func:`~django.test.utils.teardown_test_environment`.
|
||
|
||
* The :djadmin:`makemessages` command now requires configured settings, like
|
||
most other commands.
|
||
|
||
* The undocumented ``DateTimeAwareJSONEncoder`` alias for
|
||
:class:`~django.core.serializers.json.DjangoJSONEncoder` (renamed in Django
|
||
1.0) is removed.
|
||
|
||
* The :class:`cached template loader <django.template.loaders.cached.Loader>`
|
||
is now enabled if :setting:`DEBUG` is ``False`` and
|
||
:setting:`OPTIONS['loaders'] <TEMPLATES-OPTIONS>` isn't specified. This could
|
||
be backwards-incompatible if you have some :ref:`template tags that aren't
|
||
thread safe <template_tag_thread_safety>`.
|
||
|
||
.. _deprecated-features-1.11:
|
||
|
||
Features deprecated in 1.11
|
||
===========================
|
||
|
||
Miscellaneous
|
||
-------------
|
||
|
||
* ``contrib.auth``’s ``login()`` and ``logout()`` function-based views are
|
||
deprecated in favor of new class-based views
|
||
:class:`~django.contrib.auth.views.LoginView` and
|
||
:class:`~django.contrib.auth.views.LogoutView`.
|
||
|
||
* The unused ``extra_context`` parameter of
|
||
``contrib.auth.views.logout_then_login()`` is deprecated.
|
||
|
||
* ``contrib.auth``’s ``password_change()``, ``password_change_done()``,
|
||
``password_reset()``, ``password_reset_done()``, ``password_reset_confirm()``,
|
||
and ``password_reset_complete()`` function-based views are deprecated in favor
|
||
of new class-based views
|
||
:class:`~django.contrib.auth.views.PasswordChangeView`,
|
||
:class:`~django.contrib.auth.views.PasswordChangeDoneView`,
|
||
:class:`~django.contrib.auth.views.PasswordResetView`,
|
||
:class:`~django.contrib.auth.views.PasswordResetDoneView`,
|
||
:class:`~django.contrib.auth.views.PasswordResetConfirmView`, and
|
||
:class:`~django.contrib.auth.views.PasswordResetCompleteView`.
|
||
|
||
* ``django.test.runner.setup_databases()`` is moved to
|
||
:func:`django.test.utils.setup_databases`. The old location is deprecated.
|
||
|
||
* ``django.utils.translation.string_concat()`` is deprecated in
|
||
favor of :func:`django.utils.text.format_lazy`. ``string_concat(*strings)``
|
||
can be replaced by ``format_lazy('{}' * len(strings), *strings)``.
|
||
|
||
* For the ``PyLibMCCache`` cache backend, passing ``pylibmc`` behavior settings
|
||
as top-level attributes of ``OPTIONS`` is deprecated. Set them under a
|
||
``behaviors`` key within ``OPTIONS`` instead.
|