123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817 |
- ============================================
- 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
- ========================
- Security enhancements
- ~~~~~~~~~~~~~~~~~~~~~
- Several features of the django-secure_ third-party library have been
- integrated into Django. :class:`django.middleware.security.SecurityMiddleware`
- provides several security enhancements to the request/response cycle. The new
- :djadminopt:`--deploy` option of the :djadmin:`check` command allows you to
- check your production settings file for ways to increase the security of your
- site.
- .. _django-secure: https://pypi.python.org/pypi/django-secure
- New data types
- ~~~~~~~~~~~~~~
- * Django now has a :class:`~django.db.models.UUIDField` for storing
- universally unique identifiers. There is a corresponding :class:`form field
- <django.forms.UUIDField>`. It is stored as the native ``uuid`` data type on
- PostgreSQL and as a fixed length character field on other backends.
- Minor features
- ~~~~~~~~~~~~~~
- :mod:`django.contrib.admin`
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^
- * :class:`~django.contrib.admin.ModelAdmin` now has a
- :meth:`~django.contrib.admin.ModelAdmin.has_module_permission`
- method to allow limiting access to the module on the admin index page.
- * :class:`~django.contrib.admin.InlineModelAdmin` now has an attribute
- :attr:`~django.contrib.admin.InlineModelAdmin.show_change_link` that
- supports showing a link to an inline object's change form.
- * Use the new ``django.contrib.admin.RelatedOnlyFieldListFilter`` in
- :attr:`ModelAdmin.list_filter <django.contrib.admin.ModelAdmin.list_filter>`
- to limit the ``list_filter`` choices to foreign objects which are attached to
- those from the ``ModelAdmin``.
- * The :meth:`ModelAdmin.delete_view()
- <django.contrib.admin.ModelAdmin.delete_view>` displays a summary of objects
- to be deleted on the deletion confirmation page.
- * The jQuery library embedded in the admin has been upgraded to version 1.11.1.
- * You can now specify :attr:`AdminSite.site_url
- <django.contrib.admin.AdminSite.site_url>` in order to display a link to the
- front-end site.
- * You can now specify :attr:`ModelAdmin.show_full_result_count
- <django.contrib.admin.ModelAdmin.show_full_result_count>` to control whether
- or not the full count of objects should be displayed on a filtered admin page.
- :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.
- * :class:`~django.contrib.auth.forms.PasswordResetForm` now
- has a method :meth:`~django.contrib.auth.forms.PasswordResetForm.send_email`
- that can be overridden to customize the mail to be sent.
- * The ``max_length`` of :attr:`Permission.name
- <django.contrib.auth.models.Permission.name>` has been increased from 50 to
- 255 characters. Please run the database migration.
- * :attr:`~django.contrib.auth.models.CustomUser.USERNAME_FIELD` and
- :attr:`~django.contrib.auth.models.CustomUser.REQUIRED_FIELDS` now supports
- :class:`~django.db.models.ForeignKey`\s.
- :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.
- :mod:`django.contrib.gis`
- ^^^^^^^^^^^^^^^^^^^^^^^^^^
- * Compatibility shims for ``SpatialRefSys`` and ``GeometryColumns`` changed in
- Django 1.2 have been removed.
- * The Spatialite backend now supports ``Collect`` and ``Extent`` aggregates
- when the database version is 3.0 or later.
- :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.
- :mod:`django.contrib.sitemaps`
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- * The new :attr:`Sitemap.i18n <django.contrib.sitemaps.Sitemap.i18n>` attribute
- allows you to generate a sitemap based on the :setting:`LANGUAGES` setting.
- :mod:`django.contrib.sites`
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^
- * :func:`~django.contrib.sites.shortcuts.get_current_site` will now lookup
- the current site based on :meth:`request.get_host()
- <django.http.HttpRequest.get_host>` if the :setting:`SITE_ID` setting is not
- defined.
- :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.
- * The SMTP email backend now supports ``keyfile`` and ``certfile``
- authentication with the :setting:`EMAIL_SSL_CERTFILE` and
- :setting:`EMAIL_SSL_KEYFILE` settings.
- * The SMTP :class:`~django.core.mail.backends.smtp.EmailBackend` now supports
- setting the ``timeout`` parameter with the :setting:`EMAIL_TIMEOUT` setting.
- File Storage
- ^^^^^^^^^^^^
- * ...
- File Uploads
- ^^^^^^^^^^^^
- * ...
- Forms
- ^^^^^
- * Form widgets now render attributes with a value of ``True`` or ``False``
- as HTML5 boolean attributes.
- * 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.
- * After an :class:`~django.forms.ImageField` has been cleaned and validated, the
- ``UploadedFile`` object will have an additional ``image`` attribute containing
- the Pillow ``Image`` instance used to check if the file was a valid image. It
- will also update ``UploadedFile.content_type`` with the image's content type
- as determined by Pillow.
- Generic Views
- ^^^^^^^^^^^^^
- * Generic views that use :class:`~django.views.generic.list.MultipleObjectMixin`
- may now specify the ordering applied to the
- :attr:`~django.views.generic.list.MultipleObjectMixin.queryset` by setting
- :attr:`~django.views.generic.list.MultipleObjectMixin.ordering` or overriding
- :meth:`~django.views.generic.list.MultipleObjectMixin.get_ordering()`.
- * The new :attr:`SingleObjectMixin.query_pk_and_slug
- <django.views.generic.detail.SingleObjectMixin.query_pk_and_slug>`
- attribute allows changing the behavior of
- :meth:`~django.views.generic.detail.SingleObjectMixin.get_object()`
- so that it'll perform its lookup using both the primary key and the slug.
- 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.
- Management Commands
- ^^^^^^^^^^^^^^^^^^^
- * :djadmin:`dumpdata` now has the option :djadminopt:`--output` which allows
- specifying the file to which the serialized data is written.
- * :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.
- * :djadmin:`inspectdb` now outputs ``Meta.unique_together``.
- * When calling management commands from code through :ref:`call_command
- <call-command>` and passing options, the option name can match the command
- line option name (without the initial dashes) or the final option destination
- variable name, but in either case, the resulting option received by the
- command is now always the ``dest`` name specified in the command option
- definition (as long as the command uses the new :py:mod:`argparse` module).
- * The :djadmin:`dbshell` command now supports MySQL's optional SSL certificate
- authority setting (``--ssl-ca``).
- * The :djadminopt:`--name` option for :djadmin:`makemigrations` allows you to
- to give the migration(s) a custom name instead of a generated one.
- * :djadmin:`makemigrations` can now serialize timezone-aware values.
- Migrations
- ^^^^^^^^^^
- * The :class:`~django.db.migrations.operations.RunSQL` operation can now handle
- parameters passed to the SQL statements.
- Models
- ^^^^^^
- * Django now logs at most 9000 queries in ``connections.queries``, in order
- to prevent excessive memory usage in long-running processes in debug mode.
- * There is now a model ``Meta`` option to define a
- :attr:`default related name <django.db.models.Options.default_related_name>`
- for all relational fields of a model.
- * Pickling models and querysets across different versions of Django isn't
- officially supported (it may work, but there's no guarantee). An extra
- variable that specifies the current Django version is now added to the
- pickled state of models and querysets, and Django raises a ``RuntimeWarning``
- when these objects are unpickled in a different version than the one in
- which they were pickled.
- * Added :meth:`Model.from_db() <django.db.models.Model.from_db()>` which
- Django uses whenever objects are loaded using the ORM. The method allows
- customizing model loading behavior.
- * ``extra(select={...})`` now allows you to escape a literal ``%s`` sequence
- using ``%%s``.
- 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.
- * The ``environ`` argument, which contains the WSGI environment structure from
- the request, was added to the :data:`~django.core.signals.request_started`
- signal.
- Templates
- ^^^^^^^^^
- * :tfilter:`urlize` now supports domain-only links that include characters after
- the top-level domain (e.g. ``djangoproject.com/`` and
- ``djangoproject.com/download/``).
- Requests and Responses
- ^^^^^^^^^^^^^^^^^^^^^^
- * ``WSGIRequest`` now respects paths starting with ``//``.
- * The :meth:`HttpRequest.build_absolute_uri()
- <django.http.HttpRequest.build_absolute_uri>` method now handles paths
- starting with ``//`` correctly.
- * If :setting:`DEBUG` is ``True`` and a request raises a
- :exc:`~django.core.exceptions.SuspiciousOperation`, the response will be
- rendered with a detailed error page.
- * The ``query_string`` argument of :class:`~django.http.QueryDict` is now
- optional, defaulting to ``None``, so a blank ``QueryDict`` can now be
- instantiated with ``QueryDict()`` instead of ``QueryDict(None)`` or
- ``QueryDict('')``.
- * The ``GET`` and ``POST`` attributes of an :class:`~django.http.HttpRequest`
- object are now :class:`~django.http.QueryDict`\s rather than dictionaries,
- and the ``FILES`` attribute is now a ``MultiValueDict``.
- This brings this class into line with the documentation and with
- ``WSGIRequest``.
- * The :attr:`HttpResponse.charset <django.http.HttpResponse.charset>` attribute
- was added.
- 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.
- * 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.
- * Added the :attr:`~django.test.Response.resolver_match` attribute to test
- client responses.
- * Added several settings that allow customization of test tablespace parameters
- for Oracle: :setting:`DATAFILE`, :setting:`DATAFILE_TMP`,
- :setting:`DATAFILE_MAXSIZE` and :setting:`DATAFILE_TMP_MAXSIZE`.
- 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
- 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.
- Assigning 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.
- Management commands that only accept positional arguments
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- If you have written a custom management command that only accepts positional
- arguments and you didn't specify the
- :attr:`~django.core.management.BaseCommand.args` command variable, you might
- get an error like ``Error: unrecognized arguments: ...``, as variable parsing
- is now based on :py:mod:`argparse` which doesn't implicitly accept positional
- arguments. You can make your command backwards compatible by simply setting the
- :attr:`~django.core.management.BaseCommand.args` class variable. However, if
- you don't have to keep compatibility with older Django versions, it's better to
- implement the new :meth:`~django.core.management.BaseCommand.add_arguments`
- method as described in :doc:`/howto/custom-management-commands`.
- Custom test management command arguments through test runner
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The method to add custom arguments to the `test` management command through the
- test runner has changed. Previously, you could provide an `option_list` class
- variable on the test runner to add more arguments (à la :py:mod:`optparse`).
- Now to implement the same behavior, you have to create an
- ``add_arguments(cls, parser)`` class method on the test runner and call
- ``parser.add_argument`` to add any custom arguments, as parser is now an
- :py:class:`argparse.ArgumentParser` instance.
- Model check ensures auto-generated column names are within limits specified by database
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- A field name that's longer than the column name length supported by a database
- can create problems. For example, with MySQL you'll get an exception trying to
- create the column, and with PostgreSQL the column name is truncated by the
- database (you may see a warning in the PostgreSQL logs).
- A model check has been introduced to better alert users to this scenario before
- the actual creation of database tables.
- If you have an existing model where this check seems to be a false positive,
- for example on PostgreSQL where the name was already being truncated, simply
- use :attr:`~django.db.models.Field.db_column` to specify the name that's being
- used.
- The check also applies to the columns generated in an implicit
- ``ManyToManyField.through`` model. If you run into an issue there, use
- :attr:`~django.db.models.ManyToManyField.through` to create an explicit model
- and then specify :attr:`~django.db.models.Field.db_column` on its column(s)
- as needed.
- Query relation lookups now check object types
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Querying for model lookups now checks if the object passed is of correct type
- and raises a :exc:`ValueError` if not. Previously, Django didn't care if the
- object was of correct type; it just used the object's related field attribute
- (e.g. ``id``) for the lookup. Now, an error is raised to prevent incorrect
- lookups::
- >>> book = Book.objects.create(name="Django")
- >>> book = Book.objects.filter(author=book)
- Traceback (most recent call last):
- ...
- ValueError: Cannot query "<Book: Django>": Must be "Author" instance.
- Default ``EmailField.max_length`` increased to 254
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The old default 75 character ``max_length`` was not capable of storing all
- possible RFC3696/5321-compliant email addresses. In order to store all
- possible valid email addresses, the ``max_length`` has been increased to 254
- characters. You will need to generate and apply database migrations for your
- affected models (or add ``max_length=75`` if you wish to keep the length on
- your current fields). A migration for
- :attr:`django.contrib.auth.models.User.email` is included.
- Support for PostgreSQL versions older than 9.0
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The end of upstream support periods was reached in July 2014 for PostgreSQL 8.4.
- As a consequence, Django 1.8 sets 9.0 as the minimum PostgreSQL version it
- officially supports.
- This also includes dropping support for PostGIS 1.3 and 1.4 as these versions
- are not supported on versions of PostgreSQL later than 8.4.
- Django also now requires the use of Psycopg2 version 2.0.9 or higher.
- Support for MySQL versions older than 5.5
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The end of upstream support periods was reached in January 2012 for MySQL 5.0
- and December 2013 for MySQL 5.1. As a consequence, Django 1.8 sets 5.5 as the
- minimum MySQL version it officially supports.
- Support for Oracle versions older than 11.1
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The end of upstream support periods was reached in July 2010 for Oracle 9.2,
- January 2012 for Oracle 10.1, and July 2013 for Oracle 10.2. As a consequence,
- Django 1.8 sets 11.1 as the minimum Oracle version it officially supports.
- Specific privileges used instead of roles for tests on Oracle
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Earlier versions of Django granted the CONNECT and RESOURCE roles to the test
- user on Oracle. These roles have been deprecated, so Django 1.8 uses the
- specific underlying privileges instead. This changes the privileges required
- of the main user for running tests (unless the project is configured to avoid
- creating a test user). The exact privileges required now are detailed in
- :ref:`Oracle notes <oracle-notes>`.
- ``AbstractUser.last_login`` allows null values
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The :attr:`AbstractUser.last_login <django.contrib.auth.models.User.last_login>`
- field now allows null values. Previously, it defaulted to the time when the user
- was created which was misleading if the user never logged in. Please run the
- database migration. If your custom user inherits from ``AbstractUser`` and you
- wish to set ``last_login`` to ``NULL`` for users who haven't logged in, you can
- run this query::
- from django.db import models
- from django.contrib.auth import get_user_model
- from django.contrib.auth.models import AbstractBaseUser
- UserModel = get_user_model()
- if issubclass(UserModel, AbstractBaseUser):
- UserModel._default_manager.filter(
- last_login=models.F('date_joined')
- ).update(last_login=None)
- Miscellaneous
- ~~~~~~~~~~~~~
- * ``connections.queries`` is now a read-only attribute.
- * Database connections are considered equal only if they're the same object.
- They aren't hashable any more.
- * :class:`~django.middleware.gzip.GZipMiddleware` used to disable compression
- for some content types when the request is from Internet Explorer, in order
- to work around a bug in IE6 and earlier. This behavior could affect
- performance on IE7 and later. It was removed.
- * ``URLField.to_python`` no longer adds a trailing slash to pathless URLs.
- * ``django.contrib.gis`` dropped support for GEOS 3.1 and GDAL 1.6.
- * The :tfilter:`length` template filter now returns ``0`` for an undefined
- variable, rather than an empty string.
- * Support for SpatiaLite < 2.4 has been dropped.
- * ``ForeignKey.default_error_message['invalid']`` has been changed from
- ``'%(model)s instance with pk %(pk)r does not exist.'`` to
- ``'%(model)s instance with %(field)s %(value)r does not exist.'`` If you are
- using this message in your own code, please update the list of interpolated
- parameters. Internally, Django will continue to provide the
- ``pk`` parameter in ``params`` for backwards compatibility.
- * ``UserCreationForm.errors_messages['duplicate_username']`` is no longer used.
- If you wish to customize that error message, :ref:`override it on the form
- <modelforms-overriding-default-fields>` using the ``'unique'`` key in
- ``Meta.errors_messages['username']`` or, if you have a custom form field for
- ``'username'``, using the the ``'unique'`` key in its
- :attr:`~django.forms.Field.error_messages` argument.
- * ``AdminSite`` no longer takes an ``app_name`` argument and its ``app_name``
- attribute has been removed. The application name is always ``admin`` (as
- opposed to the instance name which you can still customize using
- ``AdminSite(name="...")``.
- * Internal changes were made to the :class:`~django.forms.ClearableFileInput`
- widget to allow more customization. The undocumented ``url_markup_template``
- attribute was removed in favor of ``template_with_initial``.
- * For consistency with other major vendors, the ``en_GB`` locale now has Monday
- as the first day of the week.
- * Seconds have been removed from any locales that had them in ``TIME_FORMAT``,
- ``DATETIME_FORMAT``, or ``SHORT_DATETIME_FORMAT``.
- * The default max size of the Oracle test tablespace has increased from 200M
- to 500M.
- .. _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.
- 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),
- ]
- Passing a string as ``view`` to :func:`~django.conf.urls.url`
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Related to the previous item, referencing views as strings in the ``url()``
- function is deprecated. Pass the callable view as described in the previous
- section instead.
- ``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
- the ``url`` that references :func:`django.contrib.sitemaps.views.sitemap`::
- from django.contrib.sitemaps.views import sitemap
- url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps},
- name='django.contrib.sitemaps.views.sitemap')
- to ensure compatibility when reversing by Python path is removed in Django 2.0.
- Similarly for GIS sitemaps, add ``name='django.contrib.gis.sitemaps.views.kml'``
- or ``name='django.contrib.gis.sitemaps.views.kmz'``.
- .. _security issue: https://www.djangoproject.com/weblog/2014/apr/21/security/#s-issue-unexpected-code-execution-using-reverse
- Extending management command arguments through ``Command.option_list``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Management commands now use :py:mod:`argparse` instead of :py:mod:`optparse` to
- parse command-line arguments passed to commands. This also means that the way
- to add custom arguments to commands has changed: instead of extending the
- ``option_list`` class list, you should now override the
- :meth:`~django.core.management.BaseCommand.add_arguments` method and add
- arguments through ``argparse.add_argument()``. See
- :ref:`this example <custom-commands-options>` for more details.
- ``django.core.management.NoArgsCommand``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The class :class:`~django.core.management.NoArgsCommand` is now deprecated and
- will be removed in Django 2.0. Use :class:`~django.core.management.BaseCommand`
- instead, which takes no arguments by default.
- ``cache_choices`` option of ``ModelChoiceField`` and ``ModelMultipleChoiceField``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- :class:`~django.forms.ModelChoiceField` and
- :class:`~django.forms.ModelMultipleChoiceField` took an undocumented, untested
- option ``cache_choices``. This cached querysets between multiple renderings of
- the same ``Form`` object. This option is subject to an accelerated deprecation
- and will be removed in Django 1.9.
- ``django.template.resolve_variable()``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The function has been informally marked as "Deprecated" for some time. Replace
- ``resolve_variable(path, context)`` with
- ``django.template.Variable(path).resolve(context)``.
- ``django.contrib.webdesign``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- It provided the :ttag:`lorem` template tag which is now included in the
- built-in tags. Simply remove ``'django.contrib.webdesign'`` from
- :setting:`INSTALLED_APPS` and ``{% load webdesign %}`` from your templates.
- ``error_message`` argument to ``django.forms.RegexField``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- It provided backwards compatibility for pre-1.0 code, but its functionality is
- redundant. Use ``Field.error_messages['invalid']`` instead.
- Old :tfilter:`unordered_list` syntax
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- An older (pre-1.0), more restrictive and verbose input format for the
- :tfilter:`unordered_list` template filter has been deprecated::
- ``['States', [['Kansas', [['Lawrence', []], ['Topeka', []]]], ['Illinois', []]]]``
- Using the new syntax, this becomes::
- ``['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]``
- ``django.forms.Field._has_changed()``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Rename this method to :meth:`~django.forms.Field.has_changed` by removing the
- leading underscore. The old name will still work until Django 2.0.
- ``django.utils.html.remove_tags()`` and ``removetags`` template filter
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ``django.utils.html.remove_tags()`` as well as the template filter
- ``removetags`` have been deprecated as they cannot guarantee safe output. Their
- existence is likely to lead to their use in security-sensitive contexts where
- they are not actually safe.
- The unused and undocumented ``django.utils.html.strip_entities()`` function has
- also been deprecated.
- ``is_admin_site`` argument to ``django.contrib.auth.views.password_reset()``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- It's a legacy option that should no longer be necessary.
- ``SubfieldBase``
- ~~~~~~~~~~~~~~~~
- ``django.db.models.fields.subclassing.SubfieldBase`` has been deprecated and
- will be removed in Django 2.0. Historically, it was used to handle fields where
- type conversion was needed when loading from the database, but it was not used
- in ``.values()`` calls or in aggregates. It has been replaced with
- :meth:`~django.db.models.Field.from_db_value`. Note that the new approach does
- not call the :meth:`~django.db.models.Field.to_python` method on assignment
- as was the case with ``SubfieldBase``.
|