1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777 |
- ========================
- Django 1.8 release notes
- ========================
- *April 1, 2015*
- 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.7 or older versions. We've also `begun the deprecation process for some
- features`_, and some features have reached the end of their deprecation process
- and `have been removed`_.
- Django 1.8 has been designated as Django's second :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.4, will end 6 months from the
- release date of Django 1.8.
- .. _`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`_
- .. _`have been removed`: `Features removed 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
- ========================
- ``Model._meta`` API
- ~~~~~~~~~~~~~~~~~~~
- Django now has a formalized API for :doc:`Model._meta </ref/models/meta>`,
- providing an officially supported way to :ref:`retrieve fields
- <model-meta-field-api>` and filter fields based on their :ref:`attributes
- <model-field-attributes>`.
- The ``Model._meta`` object has been part of Django since the days of pre-0.96
- "Magic Removal" -- it just wasn't an official, stable API. In recognition of
- this, we've endeavored to maintain backwards-compatibility with the old
- API endpoint where possible. However, API endpoints that aren't part of the
- new official API have been deprecated and will eventually be removed. A
- :ref:`guide to migrating from the old API to the new API
- <migrating-old-meta-api>` has been provided.
- Multiple template engines
- ~~~~~~~~~~~~~~~~~~~~~~~~~
- Django 1.8 defines a stable API for integrating template backends. It includes
- built-in support for the Django template language and for
- :class:`~django.template.backends.jinja2.Jinja2`. It supports rendering
- templates with multiple engines within the same project. Learn more about the
- new features in the :doc:`topic guide </topics/templates>` and check the
- :doc:`upgrade instructions </ref/templates/upgrading>` for details.
- 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 PostgreSQL specific functionality
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Django now has a module with extensions for PostgreSQL specific features, such
- as :class:`~django.contrib.postgres.fields.ArrayField`,
- :class:`~django.contrib.postgres.fields.HStoreField`, :ref:`range-fields`, and
- :lookup:`unaccent` lookup. A full breakdown of the features is available
- :doc:`in the documentation </ref/contrib/postgres/index>`.
- New data types
- ~~~~~~~~~~~~~~
- * Django now has a :class:`~django.db.models.UUIDField` for storing
- universally unique identifiers. It is stored as the native ``uuid`` data type
- on PostgreSQL and as a fixed length character field on other backends. There
- is a corresponding :class:`form field <django.forms.UUIDField>`.
- * Django now has a :class:`~django.db.models.DurationField` for storing periods
- of time - modeled in Python by :class:`~python:datetime.timedelta`. It is
- stored in the native ``interval`` data type on PostgreSQL, as a ``INTERVAL
- DAY(9) TO SECOND(6)`` on Oracle, and as a ``bigint`` of microseconds on other
- backends. Date and time related arithmetic has also been improved on all
- backends. There is a corresponding :class:`form field
- <django.forms.DurationField>`.
- Query Expressions, Conditional Expressions, and Database Functions
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- :doc:`Query Expressions </ref/models/expressions>` allow you to create,
- customize, and compose complex SQL expressions. This has enabled annotate
- to accept expressions other than aggregates. Aggregates are now able to
- reference multiple fields, as well as perform arithmetic, similar to ``F()``
- objects. :meth:`~django.db.models.query.QuerySet.order_by` has also gained the
- ability to accept expressions.
- :doc:`Conditional Expressions </ref/models/conditional-expressions>` allow
- you to use :keyword:`if` ... :keyword:`elif` ... :keyword:`else` logic within
- queries.
- A collection of :doc:`database functions </ref/models/database-functions>` is
- also included with functionality such as
- :class:`~django.db.models.functions.Coalesce`,
- :class:`~django.db.models.functions.Concat`, and
- :class:`~django.db.models.functions.Substr`.
- ``TestCase`` data setup
- ~~~~~~~~~~~~~~~~~~~~~~~
- :class:`~django.test.TestCase` has been refactored to allow for data
- initialization at the class level using transactions and savepoints. Database
- backends which do not support transactions, like MySQL with the MyISAM storage
- engine, will still be able to run these tests but won't benefit from the
- improvements. Tests are now run within two nested
- :func:`~django.db.transaction.atomic()` blocks: one for the whole class and one
- for each test.
- * The class method
- :meth:`TestCase.setUpTestData() <django.test.TestCase.setUpTestData>` adds
- the ability to setup test data at the class level. Using this technique can
- speed up the tests as compared to using ``setUp()``.
- * Fixture loading within ``TestCase`` is now performed once for the whole
- ``TestCase``.
- 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.2.
- * 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.
- * The ``AdminSite.password_change()`` method now has an ``extra_context``
- parameter.
- * You can now control who may login to the admin site by overriding only
- :meth:`AdminSite.has_permission()
- <django.contrib.admin.AdminSite.has_permission>` and
- :attr:`AdminSite.login_form <django.contrib.admin.AdminSite.login_form>`.
- The ``base.html`` template has a new block ``usertools`` which contains the
- user-specific header. A new context variable ``has_permission``, which gets
- its value from :meth:`~django.contrib.admin.AdminSite.has_permission`,
- indicates whether the user may access the site.
- * Foreign key dropdowns now have buttons for changing or deleting related
- objects using a popup.
- :mod:`django.contrib.admindocs`
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- * reStructuredText is now parsed in model docstrings.
- :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.
- * The default iteration count for the PBKDF2 password hasher has been
- increased by 33%. This backwards compatible change will not affect users who
- have subclassed ``django.contrib.auth.hashers.PBKDF2PasswordHasher`` to
- change the default value.
- :mod:`django.contrib.gis`
- ^^^^^^^^^^^^^^^^^^^^^^^^^^
- * A new :doc:`GeoJSON serializer </ref/contrib/gis/serializers>` is now
- available.
- * It is now allowed to include a subquery as a geographic lookup argument, for
- example ``City.objects.filter(point__within=Country.objects.filter(continent='Africa').values('mpoly'))``.
- * The Spatialite backend now supports ``Collect`` and ``Extent`` aggregates
- when the database version is 3.0 or later.
- * The PostGIS 2 ``CREATE EXTENSION postgis`` and the Spatialite
- ``SELECT InitSpatialMetaData`` initialization commands are now automatically
- run by :djadmin:`migrate`.
- * The GDAL interface now supports retrieving properties of
- :ref:`raster (image) data file <raster-data-source-objects>`.
- * Compatibility shims for ``SpatialRefSys`` and ``GeometryColumns`` changed in
- Django 1.2 have been removed.
- * All GDAL-related exceptions are now raised with ``GDALException``. The former
- ``OGRException`` has been kept for backwards compatibility but should not be
- used any longer.
- :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.
- * The default :class:`~django.contrib.sites.models.Site` created when running
- ``migrate`` now respects the :setting:`SITE_ID` setting (instead of always
- using ``pk=1``).
- Cache
- ^^^^^
- * The ``incr()`` method of the
- ``django.core.cache.backends.locmem.LocMemCache`` backend is now thread-safe.
- Cryptography
- ^^^^^^^^^^^^
- * The ``max_age`` parameter of the
- :meth:`django.core.signing.TimestampSigner.unsign` method now also accepts a
- :py:class:`datetime.timedelta` object.
- Database backends
- ^^^^^^^^^^^^^^^^^
- * The MySQL backend no longer strips microseconds from ``datetime`` values as
- MySQL 5.6.4 and up supports fractional seconds depending on the declaration
- of the datetime field (when ``DATETIME`` includes fractional precision greater
- than 0). New datetime database columns created with Django 1.8 and MySQL 5.6.4
- and up will support microseconds. See the :ref:`MySQL database notes
- <mysql-fractional-seconds>` for more details.
- * The MySQL backend no longer creates explicit indexes for foreign keys when
- using the InnoDB storage engine, as MySQL already creates them automatically.
- * The Oracle backend no longer defines the ``connection_persists_old_columns``
- feature as ``True``. Instead, Oracle will now include a cache busting clause
- when getting the description of a table.
- 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.
- * :class:`~django.core.mail.EmailMessage` and ``EmailMultiAlternatives`` now
- support the ``reply_to`` parameter.
- File Storage
- ^^^^^^^^^^^^
- * :meth:`Storage.get_available_name()
- <django.core.files.storage.Storage.get_available_name>` and
- :meth:`Storage.save() <django.core.files.storage.Storage.save>`
- now take a ``max_length`` argument to implement storage-level maximum
- filename length constraints. Filenames exceeding this argument will get
- truncated. This prevents a database error when appending a unique suffix to a
- long filename that already exists on the storage. See the :ref:`deprecation
- note <storage-max-length-update>` about adding this argument to your custom
- storage classes.
- 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.SelectDateWidget` now accepts an
- :attr:`~django.forms.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.
- * You can now pass a callable that returns an iterable of choices when
- instantiating a :class:`~django.forms.ChoiceField`.
- 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.
- * The :meth:`~django.views.generic.edit.FormMixin.get_form()` method doesn't
- require a ``form_class`` to be provided anymore. If not provided ``form_class``
- defaults to :meth:`~django.views.generic.edit.FormMixin.get_form_class()`.
- * Placeholders in :attr:`ModelFormMixin.success_url
- <django.views.generic.edit.ModelFormMixin.success_url>` now support the Python
- :py:meth:`str.format()` syntax. The legacy ``%(<foo>)s`` syntax is still
- supported but will be removed in Django 1.10.
- 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.
- Logging
- ^^^^^^^
- * The :class:`django.utils.log.AdminEmailHandler` class now has a
- :meth:`~django.utils.log.AdminEmailHandler.send_mail` method to make it more
- subclass friendly.
- Management Commands
- ^^^^^^^^^^^^^^^^^^^
- * Database connections are now always closed after a management command called
- from the command line has finished doing its job.
- * Commands from alternate package formats like eggs are now also discovered.
- * :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.
- * :djadmin:`compilemessages` now has a ``--use-fuzzy`` or ``-f`` option which
- includes fuzzy translations into compiled files.
- * 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``. It is also able to
- introspect :class:`~django.db.models.AutoField` for MySQL and PostgreSQL
- databases.
- * 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.
- * The :djadmin:`loaddata` command now prevents repeated fixture loading. If
- :setting:`FIXTURE_DIRS` contains duplicates or a default fixture directory
- path (``app_name/fixtures``), an exception is raised.
- * :djadmin:`makemigrations` now supports an :djadminopt:`--exit` option to
- exit with an error code if no migrations are created.
- * The new :djadmin:`showmigrations` command allows listing all migrations and
- their dependencies in a project.
- Middleware
- ^^^^^^^^^^
- * The :attr:`CommonMiddleware.response_redirect_class
- <django.middleware.common.CommonMiddleware.response_redirect_class>`
- attribute allows you to customize the redirects issued by the middleware.
- * A debug message will be logged to the ``django.request`` logger when a
- middleware raises a :exc:`~django.core.exceptions.MiddlewareNotUsed` exception
- in :setting:`DEBUG` mode.
- Migrations
- ^^^^^^^^^^
- * The :class:`~django.db.migrations.operations.RunSQL` operation can now handle
- parameters passed to the SQL statements.
- * It is now possible to have migrations (most probably :ref:`data migrations
- <data-migrations>`) for applications without models.
- * Migrations can now :ref:`serialize model managers
- <using-managers-in-migrations>` as part of the model state.
- * A :ref:`generic mechanism to handle the deprecation of model fields
- <migrations-removing-model-fields>` was added.
- * The :meth:`RunPython.noop() <django.db.migrations.operations.RunPython.noop>`
- and :attr:`RunSQL.noop <django.db.migrations.operations.RunSQL.noop>` class
- method/attribute were added to ease in making ``RunPython`` and ``RunSQL``
- operations reversible.
- * The migration operations :class:`~django.db.migrations.operations.RunPython`
- and :class:`~django.db.migrations.operations.RunSQL` now call the
- :meth:`allow_migrate` method of database routers. The router can use the
- newly introduced ``app_label`` and ``hints`` arguments to make a routing
- decision. To take advantage of this feature you need to update the router to
- the new ``allow_migrate`` signature, see the :ref:`deprecation section
- <deprecated-signature-of-allow-migrate>` for more details.
- 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``.
- * :doc:`Custom Lookups</howto/custom-lookups>` can now be registered using
- a decorator pattern.
- * The new :attr:`Transform.bilateral <django.db.models.Transform.bilateral>`
- attribute allows creating bilateral transformations. These transformations
- are applied to both ``lhs`` and ``rhs`` when used in a lookup expression,
- providing opportunities for more sophisticated lookups.
- * SQL special characters (\, %, _) are now escaped properly when a pattern
- lookup (e.g. ``contains``, ``startswith``, etc.) is used with an ``F()``
- expression as the right-hand side. In those cases, the escaping is performed
- by the database, which can lead to somewhat complex queries involving nested
- ``REPLACE`` function calls.
- * You can now refresh model instances by using :meth:`Model.refresh_from_db()
- <django.db.models.Model.refresh_from_db>`.
- * You can now get the set of deferred fields for a model using
- :meth:`Model.get_deferred_fields() <django.db.models.Model.get_deferred_fields>`.
- * Model field ``default``’s are now used when primary key field's are set to
- ``None``.
- 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.
- * You can now import the :func:`~django.test.signals.setting_changed` signal
- from ``django.core.signals`` to avoid loading ``django.test`` in non-test
- situations. Django no longer does so itself.
- System Check Framework
- ^^^^^^^^^^^^^^^^^^^^^^
- * :attr:`~django.core.checks.register` can now be used as a function.
- Templates
- ^^^^^^^^^
- * :tfilter:`urlize` now supports domain-only links that include characters after
- the top-level domain (e.g. ``djangoproject.com/`` and
- ``djangoproject.com/download/``).
- * :tfilter:`urlize` doesn't treat exclamation marks at the end of a domain or
- its query string as part of the URL (the URL in e.g. ``'djangoproject.com!``
- is ``djangoproject.com``)
- * Added a :class:`locmem.Loader <django.template.loaders.locmem.Loader>`
- class that loads Django templates from a Python dictionary.
- * The :ttag:`now` tag can now store its output in a context variable with the
- usual syntax: ``{% now 'j n Y' as varname %}``.
- 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.
- * ``WSGIRequestHandler`` now follows RFC in converting URI to IRI, using
- ``uri_to_iri()``.
- * The :meth:`HttpRequest.get_full_path()
- <django.http.HttpRequest.get_full_path>` method now escapes unsafe characters
- from the path portion of a Uniform Resource Identifier (URI) properly.
- * :class:`~django.http.HttpResponse` now implements a few additional methods
- like :meth:`~django.http.HttpResponse.getvalue` so that instances can be used
- as stream objects.
- * The new :meth:`HttpResponse.setdefault()
- <django.http.HttpResponse.setdefault>` method allows setting a header unless
- it has already been set.
- * You can use the new :class:`~django.http.FileResponse` to stream files.
- * The :func:`~django.views.decorators.http.condition` decorator for
- conditional view processing now supports the ``If-unmodified-since`` header.
- Tests
- ^^^^^
- * The :class:`RequestFactory.trace() <django.test.RequestFactory>`
- and :class:`Client.trace() <django.test.Client.trace>` methods were
- implemented, allowing you to create ``TRACE`` requests in your 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 options to the :djadmin:`test` command to preserve the test database
- (:djadminopt:`--keepdb`), to run the test cases in reverse order
- (:djadminopt:`--reverse`), and to enable SQL logging for failing tests
- (:djadminopt:`--debug-sql`).
- * 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`.
- * The :func:`~django.test.override_settings` decorator can now affect the
- master router in :setting:`DATABASE_ROUTERS`.
- * Added test client support for file uploads with file-like objects.
- * A shared cache is now used when testing with a SQLite in-memory database when
- using Python 3.4+ and SQLite 3.7.13+. This allows sharing the database
- between threads.
- Validators
- ^^^^^^^^^^
- * :class:`~django.core.validators.URLValidator` now supports IPv6 addresses,
- unicode domains, and URLs containing authentication data.
- 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.
- .. _unsaved-model-instance-check-18:
- Assigning unsaved objects to relations raises an error
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- .. note::
- To more easily allow in-memory usage of models, this change was reverted in
- Django 1.8.4 and replaced with a check during ``model.save()``. For example::
- >>> book = Book.objects.create(name="Django")
- >>> book.author = Author(name="John")
- >>> book.save()
- Traceback (most recent call last):
- ...
- ValueError: save() prohibited to prevent data loss due to unsaved related object 'author'.
- A similar check on assignment to reverse one-to-one relations was removed
- in Django 1.8.5.
- 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.
- If you require allowing the assignment of unsaved instances (the old behavior)
- and aren't concerned about the data loss possibility (e.g. you never save the
- objects to the database), you can disable this check by using the
- ``ForeignKey.allow_unsaved_instance_assignment`` attribute. (This attribute was
- removed in 1.8.4 as it's no longer relevant.)
- 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 ``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
- ``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.
- ``select_related()`` now checks given fields
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ``select_related()`` now validates that the given fields actually exist.
- Previously, nonexistent fields were silently ignored. Now, an error is raised::
- >>> book = Book.objects.select_related('nonexistent_field')
- Traceback (most recent call last):
- ...
- FieldError: Invalid field name(s) given in select_related: 'nonexistent_field'
- The validation also makes sure that the given field is relational::
- >>> book = Book.objects.select_related('name')
- Traceback (most recent call last):
- ...
- FieldError: Non-relational field given in select_related: 'name'
- 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.4.5 or higher (or 2.5+
- if you want to use :mod:`django.contrib.postgres`).
- 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. If you are using
- the default user (:class:`django.contrib.auth.models.User`), run the database
- migration included in ``contrib.auth``.
- If you are using a custom user model that inherits from ``AbstractUser``,
- you'll need to run :djadmin:`makemigrations` and generate a migration for your
- app that contains that model. Also, if 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)
- :mod:`django.contrib.gis`
- ~~~~~~~~~~~~~~~~~~~~~~~~~
- * Support for GEOS 3.1 and GDAL 1.6 has been dropped.
- * Support for SpatiaLite < 2.4 has been dropped.
- * GIS-specific lookups have been refactored to use the
- :class:`django.db.models.Lookup` API.
- * The default ``str`` representation of
- :class:`~django.contrib.gis.geos.GEOSGeometry` objects has been changed from
- WKT to EWKT format (including the SRID). As this representation is used in
- the serialization framework, that means that ``dumpdata`` output will now
- contain the SRID value of geometry objects.
- Priority of context processors for ``TemplateResponse`` brought in line with ``render``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The :class:`~django.template.response.TemplateResponse` constructor is designed to be a
- drop-in replacement for the :func:`~django.shortcuts.render` function. However,
- it had a slight incompatibility, in that for ``TemplateResponse``, context data
- from the passed in context dictionary could be shadowed by context data returned
- from context processors, whereas for ``render`` it was the other way
- around. This was a bug, and the behavior of ``render`` is more appropriate,
- since it allows the globally defined context processors to be overridden locally
- in the view. If you were relying on the fact context data in a
- ``TemplateResponse`` could be overridden using a context processor, you will
- need to change your code.
- Overriding ``setUpClass`` / ``tearDownClass`` in test cases
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The decorators :func:`~django.test.override_settings` and
- :func:`~django.test.modify_settings` now act at the class level when used as
- class decorators. As a consequence, when overriding ``setUpClass()`` or
- ``tearDownClass()``, the ``super`` implementation should always be called.
- Removal of ``django.contrib.formtools``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The formtools contrib app has been moved to a separate package and the
- relevant documentation pages have been updated or removed.
- The new package is available `on Github`_ and on PyPI.
- .. _on GitHub: https://github.com/django/django-formtools/
- Database connection reloading between tests
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Django previously closed database connections between each test within a
- ``TestCase``. This is no longer the case as Django now wraps the whole
- ``TestCase`` within a transaction. If some of your tests relied on the old
- behavior, you should have them inherit from ``TransactionTestCase`` instead.
- Cleanup of the ``django.template`` namespace
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- If you've been relying on private APIs exposed in the ``django.template``
- module, you may have to import them from ``django.template.base`` instead.
- Also private APIs ``django.template.base.compile_string()``,
- ``django.template.loader.find_template()``, and
- ``django.template.loader.get_template_from_string()`` were removed.
- ``model`` attribute on private model relations
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- In earlier versions of Django, on a model with a reverse foreign key
- relationship (for example), ``model._meta.get_all_related_objects()`` returned
- the relationship as a ``django.db.models.related.RelatedObject`` with the
- ``model`` attribute set to the source of the relationship. Now, this method
- returns the relationship as ``django.db.models.fields.related.ManyToOneRel``
- (private API ``RelatedObject`` has been removed), and the ``model`` attribute
- is set to the target of the relationship instead of the source. The source
- model is accessible on the ``related_model`` attribute instead.
- Consider this example from the tutorial in Django 1.8::
- >>> p = Poll.objects.get(pk=1)
- >>> p._meta.get_all_related_objects()
- [<ManyToOneRel: polls.choice>]
- >>> p._meta.get_all_related_objects()[0].model
- <class 'polls.models.Poll'>
- >>> p._meta.get_all_related_objects()[0].related_model
- <class 'polls.models.Choice'>
- and compare it to the behavior on older versions::
- >>> p._meta.get_all_related_objects()
- [<RelatedObject: polls:choice related to poll>]
- >>> p._meta.get_all_related_objects()[0].model
- <class 'polls.models.Choice'>
- To access the source model, you can use a pattern like this to write code that
- will work with both Django 1.8 and older versions::
- for relation in opts.get_all_related_objects():
- to_model = getattr(relation, 'related_model', relation.model)
- Also note that ``get_all_related_objects()`` is deprecated in 1.8. See the
- :ref:`upgrade guide <migrating-old-meta-api>` for the new API.
- Database backend API
- ~~~~~~~~~~~~~~~~~~~~
- The following changes to the database backend API are documented to assist
- those writing third-party backends in updating their code:
- * ``BaseDatabaseXXX`` classes have been moved to ``django.db.backends.base``.
- Please import them from the new locations::
- from django.db.backends.base.base import BaseDatabaseWrapper
- from django.db.backends.base.client import BaseDatabaseClient
- from django.db.backends.base.creation import BaseDatabaseCreation
- from django.db.backends.base.features import BaseDatabaseFeatures
- from django.db.backends.base.introspection import BaseDatabaseIntrospection
- from django.db.backends.base.introspection import FieldInfo, TableInfo
- from django.db.backends.base.operations import BaseDatabaseOperations
- from django.db.backends.base.schema import BaseDatabaseSchemaEditor
- from django.db.backends.base.validation import BaseDatabaseValidation
- * The ``data_types``, ``data_types_suffix``, and
- ``data_type_check_constraints`` attributes have moved from the
- ``DatabaseCreation`` class to ``DatabaseWrapper``.
- * The ``SQLCompiler.as_sql()`` method now takes a ``subquery`` parameter
- (:ticket:`24164`).
- * The ``BaseDatabaseOperations.date_interval_sql()`` method now only takes a
- ``timedelta`` parameter.
- :mod:`django.contrib.admin`
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * ``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="...")``.
- * The ``ModelAdmin.get_object()`` method (private API) now takes a third
- argument named ``from_field`` in order to specify which field should match
- the provided ``object_id``.
- * The :meth:`ModelAdmin.response_delete()
- <django.contrib.admin.ModelAdmin.response_delete>` method
- now takes a second argument named ``obj_id`` which is the serialized
- identifier used to retrieve the object before deletion.
- Default autoescaping of functions in ``django.template.defaultfilters``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- In order to make built-in template filters that output HTML "safe by default"
- when calling them in Python code, the following functions in
- ``django.template.defaultfilters`` have been changed to automatically escape
- their input value:
- * ``join``
- * ``linebreaksbr``
- * ``linebreaks_filter``
- * ``linenumbers``
- * ``unordered_list``
- * ``urlize``
- * ``urlizetrunc``
- You can revert to the old behavior by specifying ``autoescape=False`` if you
- are passing trusted content. This change doesn't have any effect when using
- the corresponding filters in templates.
- 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.
- * The :tfilter:`length` template filter now returns ``0`` for an undefined
- variable, rather than an empty string.
- * ``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.
- * The block ``usertools`` in the ``base.html`` template of
- :mod:`django.contrib.admin` now requires the ``has_permission`` context
- variable to be set. If you have any custom admin views that use this
- template, update them to pass :meth:`AdminSite.has_permission()
- <django.contrib.admin.AdminSite.has_permission>` as this new variable's
- value or simply include :meth:`AdminSite.each_context(request)
- <django.contrib.admin.AdminSite.each_context>` in the context.
- * 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 300M
- (or 200M, before 1.7.2) to 500M.
- * :func:`~django.core.urlresolvers.reverse` and
- :func:`~django.core.urlresolvers.reverse_lazy` now return Unicode strings
- instead of byte strings.
- * The ``CacheClass`` shim has been removed from all cache backends.
- These aliases were provided for backwards compatibility with Django 1.3.
- If you are still using them, please update your project to use the real
- class name found in the :setting:`BACKEND <CACHES-BACKEND>` key of the
- :setting:`CACHES` setting.
- * By default, :ref:`call_command <call-command>` now always skips the check
- framework (unless you pass it ``skip_checks=False``).
- * When iterating over lines, :class:`~django.core.files.File` now uses
- `universal newlines`_. The following are recognized as ending a line: the
- Unix end-of-line convention ``'\n'``, the Windows convention ``'\r\n'``, and
- the old Macintosh convention ``'\r'``.
- .. _universal newlines: https://www.python.org/dev/peps/pep-0278
- * The Memcached cache backends ``MemcachedCache`` and ``PyLibMCCache`` will
- delete a key if ``set()`` fails. This is necessary to ensure the ``cache_db``
- session store always fetches the most current session data.
- * Private APIs ``override_template_loaders`` and ``override_with_test_loader``
- in ``django.test.utils`` were removed. Override ``TEMPLATES`` with
- ``override_settings`` instead.
- * Warnings from the MySQL database backend are no longer converted to
- exceptions when :setting:`DEBUG` is ``True``.
- * :class:`~django.http.HttpRequest` now has a simplified ``repr`` (e.g.
- ``<WSGIRequest: GET '/somepath/'>``). This won't change the behavior of
- the :class:`~django.views.debug.SafeExceptionReporterFilter` class.
- * Class-based views that use :class:`~django.views.generic.edit.ModelFormMixin`
- will raise an :exc:`~django.core.exceptions.ImproperlyConfigured` exception
- when both the ``fields`` and ``form_class`` attributes are specified.
- Previously, ``fields`` was silently ignored.
- * When following redirects, the test client now raises
- :exc:`~django.test.client.RedirectCycleError` if it detects a loop or hits a
- maximum redirect limit (rather than passing silently).
- * Translatable strings set as the ``default`` parameter of the field are cast
- to concrete strings later, so the return type of ``Field.get_default()`` is
- different in some cases. There is no change to default values which are the
- result of a callable.
- * ``GenericIPAddressField.empty_strings_allowed`` is now ``False``. Database
- backends that interpret empty strings as null (only Oracle among the backends
- that Django includes) will no longer convert null values back to an empty
- string. This is consistent with other backends.
- * When the :attr:`~django.core.management.BaseCommand.leave_locale_alone`
- attribute is ``False``, translations are now deactivated instead of forcing
- the "en-us" locale. In the case your models contained non-English strings and
- you counted on English translations to be activated in management commands,
- this will not happen any longer. It might be that new database migrations are
- generated (once) after migrating to 1.8.
- * :func:`django.utils.translation.get_language()` now returns ``None`` instead
- of :setting:`LANGUAGE_CODE` when translations are temporarily deactivated.
- * When a translation doesn't exist for a specific literal, the fallback is now
- taken from the :setting:`LANGUAGE_CODE` language (instead of from the
- untranslated ``msgid`` message).
- * The ``name`` field of :class:`django.contrib.contenttypes.models.ContentType`
- has been removed by a migration and replaced by a property. That means it's
- not possible to query or filter a ``ContentType`` by this field any longer.
- * :djadmin:`migrate` now accepts the :djadminopt:`--fake-initial` option to
- allow faking initial migrations. In 1.7 initial migrations were always
- automatically faked if all tables created in an initial migration already
- existed.
- * An app *without* migrations with a ``ForeignKey`` to an app *with* migrations
- may now result in a foreign key constraint error when migrating the database
- or running tests. In Django 1.7, this could fail silently and result in a
- missing constraint. To resolve the error, add migrations to the app without
- them.
- .. _deprecated-features-1.8:
- Features deprecated in 1.8
- ==========================
- Selected methods in ``django.db.models.options.Options``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- As part of the formalization of the ``Model._meta`` API (from the
- :class:`django.db.models.options.Options` class), a number of methods have been
- deprecated and will be removed in Django 1.10:
- * ``get_all_field_names()``
- * ``get_all_related_objects()``
- * ``get_all_related_objects_with_model()``
- * ``get_all_related_many_to_many_objects()``
- * ``get_all_related_m2m_objects_with_model()``
- * ``get_concrete_fields_with_model()``
- * ``get_field_by_name()``
- * ``get_fields_with_model()``
- * ``get_m2m_with_model()``
- A :ref:`migration guide <migrating-old-meta-api>` has been provided to assist
- in converting your code from the old API to the new, official API.
- 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 1.10. 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.
- Template-related settings
- ~~~~~~~~~~~~~~~~~~~~~~~~~
- As a consequence of the multiple template engines refactor, several settings
- are deprecated in favor of :setting:`TEMPLATES`:
- * ``ALLOWED_INCLUDE_ROOTS``
- * ``TEMPLATE_CONTEXT_PROCESSORS``
- * ``TEMPLATE_DEBUG``
- * ``TEMPLATE_DIRS``
- * ``TEMPLATE_LOADERS``
- * ``TEMPLATE_STRING_IF_INVALID``
- ``django.core.context_processors``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Built-in template context processors have been moved to
- ``django.template.context_processors``.
- ``django.test.SimpleTestCase.urls``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The attribute ``SimpleTestCase.urls`` for specifying URLconf configuration in
- tests has been deprecated and will be removed in Django 1.10. 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 1.10.
- 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 1.10.
- 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
- Aggregate methods and modules
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The ``django.db.models.sql.aggregates`` and
- ``django.contrib.gis.db.models.sql.aggregates`` modules (both private API), have
- been deprecated as ``django.db.models.aggregates`` and
- ``django.contrib.gis.db.models.aggregates`` are now also responsible
- for SQL generation. The old modules will be removed in Django 1.10.
- If you were using the old modules, see :doc:`Query Expressions
- </ref/models/expressions>` for instructions on rewriting custom aggregates
- using the new stable API.
- The following methods and properties of ``django.db.models.sql.query.Query``
- have also been deprecated and the backwards compatibility shims will be removed
- in Django 1.10:
- * ``Query.aggregates``, replaced by ``annotations``.
- * ``Query.aggregate_select``, replaced by ``annotation_select``.
- * ``Query.add_aggregate()``, replaced by ``add_annotation()``.
- * ``Query.set_aggregate_mask()``, replaced by ``set_annotation_mask()``.
- * ``Query.append_aggregate_mask()``, replaced by ``append_annotation_mask()``.
- 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 ``NoArgsCommand`` is now deprecated and will be removed in Django
- 1.10. Use :class:`~django.core.management.BaseCommand` instead, which takes no
- arguments by default.
- Listing all migrations in a project
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The ``--list`` option of the :djadmin:`migrate` management command is
- deprecated and will be removed in Django 1.10. Use :djadmin:`showmigrations`
- instead.
- ``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 1.10.
- ``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 1.10. 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``.
- ``django.utils.checksums``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~
- The ``django.utils.checksums`` module has been deprecated and will be removed
- in Django 1.10. The functionality it provided (validating checksum using the
- Luhn algorithm) was undocumented and not used in Django. The module has been
- moved to the `django-localflavor`_ package (version 1.1+).
- .. _django-localflavor: https://pypi.python.org/pypi/django-localflavor
- ``InlineAdminForm.original_content_type_id``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The ``original_content_type_id`` attribute on ``InlineAdminForm`` has been
- deprecated and will be removed in Django 1.10. Historically, it was used
- to construct the "view on site" URL. This URL is now accessible using the
- ``absolute_url`` attribute of the form.
- ``django.views.generic.edit.FormMixin.get_form()``’s ``form_class`` argument
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ``FormMixin`` subclasses that override the ``get_form()`` method should make
- sure to provide a default value for the ``form_class`` argument since it's
- now optional.
- Rendering templates loaded by :func:`~django.template.loader.get_template()` with a :class:`~django.template.Context`
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The return type of :func:`~django.template.loader.get_template()` has changed
- in Django 1.8: instead of a :class:`django.template.Template`, it returns a
- ``Template`` instance whose exact type depends on which backend loaded it.
- Both classes provide a ``render()`` method, however, the former takes a
- :class:`django.template.Context` as an argument while the latter expects a
- :class:`dict`. This change is enforced through a deprecation path for Django
- templates.
- Since it's easier to understand with examples, the :ref:`upgrade guide
- <get_template-upgrade-django-18>` shows how to adapt affected code.
- All this also applies to :func:`~django.template.loader.select_template()`.
- :class:`~django.template.Template` and :class:`~django.template.Context` classes in template responses
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Some methods of :class:`~django.template.response.SimpleTemplateResponse` and
- :class:`~django.template.response.TemplateResponse` accepted
- :class:`django.template.Context` and :class:`django.template.Template` objects
- as arguments. They should now receive :class:`dict` and backend-dependent
- template objects respectively.
- This also applies to the return types if you have subclassed either template
- response class.
- Check the :doc:`template response API documentation </ref/template-response>`
- for details.
- ``current_app`` argument of template-related APIs
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The following functions and classes will no longer accept a ``current_app``
- parameter to set an URL namespace in Django 1.10:
- * ``django.shortcuts.render()``
- * ``django.template.Context()``
- * ``django.template.RequestContext()``
- * ``django.template.response.TemplateResponse()``
- Set ``request.current_app`` instead, where ``request`` is the first argument
- to these functions or classes. If you're using a plain ``Context``, use a
- ``RequestContext`` instead.
- ``dictionary`` and ``context_instance`` arguments of rendering functions
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The following functions will no longer accept the ``dictionary`` and
- ``context_instance`` parameters in Django 1.10:
- * ``django.shortcuts.render()``
- * ``django.shortcuts.render_to_response()``
- * ``django.template.loader.render_to_string()``
- Use the ``context`` parameter instead. When ``dictionary`` is passed as a
- positional argument, which is the most common idiom, no changes are needed.
- If you're passing a :class:`~django.template.Context` in ``context_instance``,
- pass a :class:`dict` in the ``context`` parameter instead. If you're passing a
- :class:`~django.template.RequestContext`, pass the request separately in the
- ``request`` parameter.
- ``dirs`` argument of template-finding functions
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The following functions will no longer accept a ``dirs`` parameter to override
- ``TEMPLATE_DIRS`` in Django 1.10:
- * :func:`django.template.loader.get_template()`
- * :func:`django.template.loader.select_template()`
- * :func:`django.shortcuts.render()`
- * :func:`django.shortcuts.render_to_response()`
- The parameter didn't work consistently across different template loaders and
- didn't work for included templates.
- ``django.template.loader.BaseLoader``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ``django.template.loader.BaseLoader`` was renamed to
- ``django.template.loaders.base.Loader``. If you've written a custom template
- loader that inherits ``BaseLoader``, you must inherit ``Loader`` instead.
- ``django.test.utils.TestTemplateLoader``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Private API ``django.test.utils.TestTemplateLoader`` is deprecated in favor of
- ``django.template.loaders.locmem.Loader`` and will be removed in Django 1.9.
- .. _storage-max-length-update:
- Support for the ``max_length`` argument on custom ``Storage`` classes
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ``Storage`` subclasses should add ``max_length=None`` as a parameter to
- :meth:`~django.core.files.storage.Storage.get_available_name` and/or
- :meth:`~django.core.files.storage.Storage.save` if they override either method.
- Support for storages that do not accept this argument will be removed in
- Django 1.10.
- ``qn`` replaced by ``compiler``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- In previous Django versions, various internal ORM methods (mostly ``as_sql``
- methods) accepted a ``qn`` (for "quote name") argument, which was a reference
- to a function that quoted identifiers for sending to the database. In Django
- 1.8, that argument has been renamed to ``compiler`` and is now a full
- ``SQLCompiler`` instance. For backwards-compatibility, calling a
- ``SQLCompiler`` instance performs the same name-quoting that the ``qn``
- function used to. However, this backwards-compatibility shim is immediately
- deprecated: you should rename your ``qn`` arguments to ``compiler``, and call
- ``compiler.quote_name_unless_alias(...)`` where you previously called
- ``qn(...)``.
- Default value of ``RedirectView.permanent``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The default value of the
- :attr:`RedirectView.permanent <django.views.generic.base.RedirectView.permanent>`
- attribute will change from ``True`` to ``False`` in Django 1.9.
- Using ``AuthenticationMiddleware`` without ``SessionAuthenticationMiddleware``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ``django.contrib.auth.middleware.SessionAuthenticationMiddleware`` was
- added in Django 1.7. In Django 1.7.2, its functionality was moved to
- ``auth.get_user()`` and, for backwards compatibility, enabled only if
- ``'django.contrib.auth.middleware.SessionAuthenticationMiddleware'`` appears in
- :setting:`MIDDLEWARE_CLASSES`.
- In Django 1.10, session verification will be enabled regardless of whether or not
- ``SessionAuthenticationMiddleware`` is enabled (at which point
- ``SessionAuthenticationMiddleware`` will have no significance). You can add it
- to your ``MIDDLEWARE_CLASSES`` sometime before then to opt-in. Please read the
- :ref:`upgrade considerations <session-invalidation-on-password-change>` first.
- ``django.contrib.sitemaps.FlatPageSitemap``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ``django.contrib.sitemaps.FlatPageSitemap`` has moved to
- ``django.contrib.flatpages.sitemaps.FlatPageSitemap``. The old import location
- is deprecated and will be removed in Django 1.9.
- Model ``Field.related``
- ~~~~~~~~~~~~~~~~~~~~~~~
- Private attribute ``django.db.models.Field.related`` is deprecated in favor
- of ``Field.rel``. The latter is an instance of
- ``django.db.models.fields.related.ForeignObjectRel`` which replaces
- ``django.db.models.related.RelatedObject``. The ``django.db.models.related``
- module has been removed and the ``Field.related`` attribute will be removed in
- Django 1.10.
- ``ssi`` template tag
- ~~~~~~~~~~~~~~~~~~~~
- The ``ssi`` template tag allows files to be included in a template by
- absolute path. This is of limited use in most deployment situations, and
- the :ttag:`include` tag often makes more sense. This tag is now deprecated and
- will be removed in Django 1.10.
- ``=`` as comparison operator in ``if`` template tag
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Using a single equals sign with the ``{% if %}`` template tag for equality
- testing was undocumented and untested. It's now deprecated in favor of ``==``.
- ``%(<foo>)s`` syntax in ``ModelFormMixin.success_url``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The legacy ``%(<foo>)s`` syntax in :attr:`ModelFormMixin.success_url
- <django.views.generic.edit.ModelFormMixin.success_url>` is deprecated and
- will be removed in Django 1.10.
- ``GeoQuerySet`` aggregate methods
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The ``collect()``, ``extent()``, ``extent3d()``, ``make_line()``, and
- ``unionagg()`` aggregate methods are deprecated and should be replaced by their
- function-based aggregate equivalents (``Collect``, ``Extent``, ``Extent3D``,
- ``MakeLine``, and ``Union``).
- .. _deprecated-signature-of-allow-migrate:
- Signature of the ``allow_migrate`` router method
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The signature of the :meth:`allow_migrate` method of database routers has
- changed from ``allow_migrate(db, model)`` to
- ``allow_migrate(db, app_label, model_name=None, **hints)``.
- When ``model_name`` is set, the value that was previously given through the
- ``model`` positional argument may now be found inside the ``hints`` dictionary
- under the key ``'model'``.
- After switching to the new signature the router will also be called by the
- :class:`~django.db.migrations.operations.RunPython` and
- :class:`~django.db.migrations.operations.RunSQL` operations.
- .. removed-features-1.8:
- Features removed in 1.8
- =======================
- These features have reached the end of their deprecation cycle and so have been
- removed in Django 1.8 (please see the :ref:`deprecation timeline
- <deprecation-removed-in-1.8>` for more details):
- * ``django.contrib.comments`` is removed.
- * The following transaction management APIs are removed:
- - ``TransactionMiddleware``
- - the decorators and context managers ``autocommit``, ``commit_on_success``,
- and ``commit_manually``, defined in ``django.db.transaction``
- - the functions ``commit_unless_managed`` and ``rollback_unless_managed``,
- also defined in ``django.db.transaction``
- - the ``TRANSACTIONS_MANAGED`` setting
- * The :ttag:`cycle` and :ttag:`firstof` template tags auto-escape their
- arguments.
- * The ``SEND_BROKEN_LINK_EMAILS`` setting is removed.
- * ``django.middleware.doc.XViewMiddleware`` is removed.
- * The ``Model._meta.module_name`` alias is removed.
- * The backward compatible shims introduced to rename ``get_query_set``
- and similar queryset methods are removed. This affects the following classes:
- ``BaseModelAdmin``, ``ChangeList``, ``BaseCommentNode``,
- ``GenericForeignKey``, ``Manager``, ``SingleRelatedObjectDescriptor`` and
- ``ReverseSingleRelatedObjectDescriptor``.
- * The backward compatible shims introduced to rename the attributes
- ``ChangeList.root_query_set`` and ``ChangeList.query_set`` are removed.
- * ``django.views.defaults.shortcut`` and ``django.conf.urls.shortcut`` are
- removed.
- * Support for the Python Imaging Library (PIL) module is removed.
- * The following private APIs are removed:
- - ``django.db.backend``
- - ``django.db.close_connection()``
- - ``django.db.backends.creation.BaseDatabaseCreation.set_autocommit()``
- - ``django.db.transaction.is_managed()``
- - ``django.db.transaction.managed()``
- * ``django.forms.widgets.RadioInput`` is removed.
- * The module ``django.test.simple`` and the class
- ``django.test.simple.DjangoTestSuiteRunner`` are removed.
- * The module ``django.test._doctest`` is removed.
- * The ``CACHE_MIDDLEWARE_ANONYMOUS_ONLY`` setting is removed. This change
- affects both ``django.middleware.cache.CacheMiddleware`` and
- ``django.middleware.cache.UpdateCacheMiddleware`` despite the lack of a
- deprecation warning in the latter class.
- * Usage of the hard-coded *Hold down "Control", or "Command" on a Mac, to select
- more than one.* string to override or append to user-provided ``help_text`` in
- forms for ``ManyToMany`` model fields is not performed by Django anymore
- either at the model or forms layer.
- * The ``Model._meta.get_(add|change|delete)_permission`` methods are removed.
- * The session key ``django_language`` is no longer read for backwards
- compatibility.
- * Geographic Sitemaps are removed
- (``django.contrib.gis.sitemaps.views.index`` and
- ``django.contrib.gis.sitemaps.views.sitemap``).
- * ``django.utils.html.fix_ampersands``, the ``fix_ampersands`` template filter,
- and ``django.utils.html.clean_html`` are removed.
|