{"title":"Django 2.0 release notes","version":"dev","locale":"en","docname":"releases/2.0","url":"/en/dev/releases/2.0/","canonical":"https://djangodocs.dev/en/dev/releases/2.0/","summary":"Welcome to Django 2.0! These release notes cover the new features, as well as some backwards incompatible changes you’ll want to be aware of when upgrading…","html":"<h1>Django 2.0 release notes<a class=\"heading-anchor\" href=\"#django-2-0-release-notes\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p><em>December 2, 2017</em></p>\n<p>Welcome to Django 2.0!</p>\n<p>These release notes cover the <a class=\"reference internal\" href=\"#whats-new-2-0\"><span class=\"std std-ref\">new features</span></a>, as well as\nsome <a class=\"reference internal\" href=\"#backwards-incompatible-2-0\"><span class=\"std std-ref\">backwards incompatible changes</span></a> you’ll\nwant to be aware of when upgrading from Django 1.11 or earlier. We’ve\n<a class=\"reference internal\" href=\"#removed-features-2-0\"><span class=\"std std-ref\">dropped some features</span></a> that have reached the end of\ntheir deprecation cycle, and we’ve <a class=\"reference internal\" href=\"#deprecated-features-2-0\"><span class=\"std std-ref\">begun the deprecation process for some\nfeatures</span></a>.</p>\n<p>This release starts Django’s use of a <a class=\"reference internal\" href=\"/en/dev/internals/release-process/#internal-release-cadence\"><span class=\"std std-ref\">loose form of semantic versioning</span></a>, but there aren’t any major backwards incompatible\nchanges that might be expected of a 2.0 release. Upgrading should be a similar\namount of effort as past feature releases.</p>\n<p>See the <a class=\"reference internal\" href=\"/en/dev/howto/upgrade-version/\"><span class=\"doc\">How to upgrade Django to a newer version</span></a> guide if you’re updating an existing\nproject.</p>\n<section id=\"python-compatibility\">\n<h2>Python compatibility<a class=\"heading-anchor\" href=\"#python-compatibility\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Django 2.0 supports Python 3.4, 3.5, 3.6, and 3.7. We <strong>highly recommend</strong> and\nonly officially support the latest release of each series.</p>\n<p>The Django 1.11.x series is the last to support Python 2.7.</p>\n<p>Django 2.0 will be the last release series to support Python 3.4. If you plan\na deployment of Python 3.4 beyond the end-of-life for Django 2.0 (April 2019),\nstick with Django 1.11 LTS (supported until April 2020) instead. Note, however,\nthat the end-of-life for Python 3.4 is March 2019.</p>\n</section>\n<section id=\"third-party-library-support-for-older-version-of-django\">\n<h2>Third-party library support for older version of Django<a class=\"heading-anchor\" href=\"#third-party-library-support-for-older-version-of-django\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Following the release of Django 2.0, we suggest that third-party app authors\ndrop support for all versions of Django prior to 1.11. At that time, you should\nbe able to run your package’s tests using <code class=\"docutils literal notranslate\">python -Wd</code> so that deprecation\nwarnings do appear. After making the deprecation warning fixes, your app should\nbe compatible with Django 2.0.</p>\n</section>\n<section id=\"what-s-new-in-django-2-0\">\n<span id=\"whats-new-2-0\"></span><h2>What’s new in Django 2.0<a class=\"heading-anchor\" href=\"#what-s-new-in-django-2-0\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"simplified-url-routing-syntax\">\n<h3>Simplified URL routing syntax<a class=\"heading-anchor\" href=\"#simplified-url-routing-syntax\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The new <a class=\"reference internal\" href=\"/en/dev/ref/urls/#django.urls.path\" title=\"django.urls.path\"><code class=\"xref py py-func docutils literal notranslate\">django.urls.path()</code></a> function allows a simpler, more readable URL\nrouting syntax. For example, this example from previous Django releases:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>url<span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s2\">&quot;^articles/(?P&lt;year&gt;[0-9]</span><span class=\"si\">{4}</span><span class=\"s2\">)/$&quot;</span><span class=\"p\">,</span> views<span class=\"o\">.</span>year_archive<span class=\"p\">),</span>\n</code></pre></div>\n<p>could be written as:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>path<span class=\"p\">(</span><span class=\"s2\">&quot;articles/&lt;int:year&gt;/&quot;</span><span class=\"p\">,</span> views<span class=\"o\">.</span>year_archive<span class=\"p\">),</span>\n</code></pre></div>\n<p>The new syntax supports type coercion of URL parameters. In the example, the\nview will receive the <code class=\"docutils literal notranslate\">year</code> keyword argument as an integer rather than as\na string. Also, the URLs that will match are slightly less constrained in the\nrewritten example. For example, the year 10000 will now match since the year\nintegers aren’t constrained to be exactly four digits long as they are in the\nregular expression.</p>\n<p>The <code class=\"docutils literal notranslate\">django.conf.urls.url()</code> function from previous versions is now available\nas <a class=\"reference internal\" href=\"/en/dev/ref/urls/#django.urls.re_path\" title=\"django.urls.re_path\"><code class=\"xref py py-func docutils literal notranslate\">django.urls.re_path()</code></a>. The old location remains for backwards\ncompatibility, without an imminent deprecation. The old\n<code class=\"docutils literal notranslate\">django.conf.urls.include()</code> function is now importable from <code class=\"docutils literal notranslate\">django.urls</code>\nso you can use <code class=\"docutils literal notranslate\">from django.urls import include, path, re_path</code> in your\nURLconfs.</p>\n<p>The <a class=\"reference internal\" href=\"/en/dev/topics/http/urls/\"><span class=\"doc\">URL dispatcher</span></a> document is rewritten to feature the new syntax\nand provide more details.</p>\n</section>\n<section id=\"mobile-friendly-contrib-admin\">\n<h3>Mobile-friendly <code class=\"docutils literal notranslate\">contrib.admin</code><a class=\"heading-anchor\" href=\"#mobile-friendly-contrib-admin\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The admin is now responsive and supports all major mobile devices. Older\nbrowsers may experience varying levels of graceful degradation.</p>\n</section>\n<section id=\"window-expressions\">\n<h3>Window expressions<a class=\"heading-anchor\" href=\"#window-expressions\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The new <a class=\"reference internal\" href=\"/en/dev/ref/models/expressions/#django.db.models.expressions.Window\" title=\"django.db.models.expressions.Window\"><code class=\"xref py py-class docutils literal notranslate\">Window</code></a> expression allows\nadding an <code class=\"docutils literal notranslate\">OVER</code> clause to querysets. You can use <a class=\"reference internal\" href=\"/en/dev/ref/models/database-functions/#window-functions\"><span class=\"std std-ref\">window functions</span></a> and <a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#aggregation-functions\"><span class=\"std std-ref\">aggregate functions</span></a> in\nthe expression.</p>\n</section>\n<section id=\"minor-features\">\n<h3>Minor features<a class=\"heading-anchor\" href=\"#minor-features\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<section id=\"django-contrib-admin\">\n<h4><a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#module-django.contrib.admin\" title=\"django.contrib.admin: Django's admin site.\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.admin</code></a><a class=\"heading-anchor\" href=\"#django-contrib-admin\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.autocomplete_fields\" title=\"django.contrib.admin.ModelAdmin.autocomplete_fields\"><code class=\"xref py py-attr docutils literal notranslate\">ModelAdmin.autocomplete_fields</code></a> attribute and\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_autocomplete_fields\" title=\"django.contrib.admin.ModelAdmin.get_autocomplete_fields\"><code class=\"xref py py-meth docutils literal notranslate\">ModelAdmin.get_autocomplete_fields()</code></a> method allow using a\n<a class=\"reference external\" href=\"https://select2.org/\">Select2</a> search widget for <code class=\"docutils literal notranslate\">ForeignKey</code> and\n<code class=\"docutils literal notranslate\">ManyToManyField</code>.</p></li>\n</ul>\n</section>\n<section id=\"django-contrib-auth\">\n<h4><a class=\"reference internal\" href=\"/en/dev/topics/auth/#module-django.contrib.auth\" title=\"django.contrib.auth: Django's authentication framework.\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.auth</code></a><a class=\"heading-anchor\" href=\"#django-contrib-auth\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>The default iteration count for the PBKDF2 password hasher is increased from\n36,000 to 100,000.</p></li>\n</ul>\n</section>\n<section id=\"django-contrib-gis\">\n<h4><a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/#module-django.contrib.gis\" title=\"django.contrib.gis: Geographic Information System (GIS) extensions for Django\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.gis</code></a><a class=\"heading-anchor\" href=\"#django-contrib-gis\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>Added MySQL support for the\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.AsGeoJSON\" title=\"django.contrib.gis.db.models.functions.AsGeoJSON\"><code class=\"xref py py-class docutils literal notranslate\">AsGeoJSON</code></a> function,\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.GeoHash\" title=\"django.contrib.gis.db.models.functions.GeoHash\"><code class=\"xref py py-class docutils literal notranslate\">GeoHash</code></a> function,\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.IsValid\" title=\"django.contrib.gis.db.models.functions.IsValid\"><code class=\"xref py py-class docutils literal notranslate\">IsValid</code></a> function,\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/geoquerysets/#std-fieldlookup-isvalid\"><code class=\"xref std std-lookup docutils literal notranslate\">isvalid</code></a> lookup, and <a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/geoquerysets/#distance-lookups\"><span class=\"std std-ref\">distance lookups</span></a>.</p></li>\n<li><p>Added the <a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.Azimuth\" title=\"django.contrib.gis.db.models.functions.Azimuth\"><code class=\"xref py py-class docutils literal notranslate\">Azimuth</code></a> and\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.LineLocatePoint\" title=\"django.contrib.gis.db.models.functions.LineLocatePoint\"><code class=\"xref py py-class docutils literal notranslate\">LineLocatePoint</code></a> functions,\nsupported on PostGIS and SpatiaLite.</p></li>\n<li><p>Any <a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/geos/#django.contrib.gis.geos.GEOSGeometry\" title=\"django.contrib.gis.geos.GEOSGeometry\"><code class=\"xref py py-class docutils literal notranslate\">GEOSGeometry</code></a> imported from GeoJSON now\nhas its SRID set.</p></li>\n<li><p>Added the <a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/forms-api/#django.contrib.gis.forms.widgets.OSMWidget.default_zoom\" title=\"django.contrib.gis.forms.widgets.OSMWidget.default_zoom\"><code class=\"xref py py-attr docutils literal notranslate\">OSMWidget.default_zoom</code></a> attribute to customize the map’s\ndefault zoom level.</p></li>\n<li><p>Made metadata readable and editable on rasters through the\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/gdal/#django.contrib.gis.gdal.GDALRaster.metadata\" title=\"django.contrib.gis.gdal.GDALRaster.metadata\"><code class=\"xref py py-attr docutils literal notranslate\">metadata</code></a>,\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/gdal/#django.contrib.gis.gdal.GDALRaster.info\" title=\"django.contrib.gis.gdal.GDALRaster.info\"><code class=\"xref py py-attr docutils literal notranslate\">info</code></a>, and\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/gdal/#django.contrib.gis.gdal.GDALBand.metadata\" title=\"django.contrib.gis.gdal.GDALBand.metadata\"><code class=\"xref py py-attr docutils literal notranslate\">metadata</code></a> attributes.</p></li>\n<li><p>Allowed passing driver-specific creation options to\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/gdal/#django.contrib.gis.gdal.GDALRaster\" title=\"django.contrib.gis.gdal.GDALRaster\"><code class=\"xref py py-class docutils literal notranslate\">GDALRaster</code></a> objects using <code class=\"docutils literal notranslate\">papsz_options</code>.</p></li>\n<li><p>Allowed creating <a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/gdal/#django.contrib.gis.gdal.GDALRaster\" title=\"django.contrib.gis.gdal.GDALRaster\"><code class=\"xref py py-class docutils literal notranslate\">GDALRaster</code></a> objects in\nGDAL’s internal virtual filesystem. Rasters can now be <a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/gdal/#gdal-raster-vsimem\"><span class=\"std std-ref\">created from and\nconverted to binary data</span></a> in-memory.</p></li>\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/gdal/#django.contrib.gis.gdal.GDALBand.color_interp\" title=\"django.contrib.gis.gdal.GDALBand.color_interp\"><code class=\"xref py py-meth docutils literal notranslate\">GDALBand.color_interp()</code></a> method returns the color\ninterpretation for the band.</p></li>\n</ul>\n</section>\n<section id=\"django-contrib-postgres\">\n<h4><a class=\"reference internal\" href=\"/en/dev/ref/contrib/postgres/#module-django.contrib.postgres\" title=\"django.contrib.postgres: PostgreSQL-specific fields and features\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.postgres</code></a><a class=\"heading-anchor\" href=\"#django-contrib-postgres\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>The new <code class=\"docutils literal notranslate\">distinct</code> argument for\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/postgres/aggregates/#django.contrib.postgres.aggregates.ArrayAgg\" title=\"django.contrib.postgres.aggregates.ArrayAgg\"><code class=\"xref py py-class docutils literal notranslate\">ArrayAgg</code></a> determines if\nconcatenated values will be distinct.</p></li>\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/contrib/postgres/functions/#django.contrib.postgres.functions.RandomUUID\" title=\"django.contrib.postgres.functions.RandomUUID\"><code class=\"xref py py-class docutils literal notranslate\">RandomUUID</code></a> database\nfunction returns a version 4 UUID. It requires use of PostgreSQL’s\n<code class=\"docutils literal notranslate\">pgcrypto</code> extension which can be activated using the new\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/postgres/operations/#django.contrib.postgres.operations.CryptoExtension\" title=\"django.contrib.postgres.operations.CryptoExtension\"><code class=\"xref py py-class docutils literal notranslate\">CryptoExtension</code></a> migration\noperation.</p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/contrib/postgres/indexes/#django.contrib.postgres.indexes.GinIndex\" title=\"django.contrib.postgres.indexes.GinIndex\"><code class=\"xref py py-class docutils literal notranslate\">django.contrib.postgres.indexes.GinIndex</code></a> now supports the\n<code class=\"docutils literal notranslate\">fastupdate</code> and <code class=\"docutils literal notranslate\">gin_pending_list_limit</code> parameters.</p></li>\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/contrib/postgres/indexes/#django.contrib.postgres.indexes.GistIndex\" title=\"django.contrib.postgres.indexes.GistIndex\"><code class=\"xref py py-class docutils literal notranslate\">GistIndex</code></a> class allows\ncreating <code class=\"docutils literal notranslate\">GiST</code> indexes in the database. The new\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/postgres/operations/#django.contrib.postgres.operations.BtreeGistExtension\" title=\"django.contrib.postgres.operations.BtreeGistExtension\"><code class=\"xref py py-class docutils literal notranslate\">BtreeGistExtension</code></a> migration\noperation installs the <code class=\"docutils literal notranslate\">btree_gist</code> extension to add support for operator\nclasses that aren’t built-in.</p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/django-admin/#django-admin-inspectdb\"><code class=\"xref std std-djadmin docutils literal notranslate\">inspectdb</code></a> can now introspect <code class=\"docutils literal notranslate\">JSONField</code> and various\n<code class=\"docutils literal notranslate\">RangeField</code>s (<code class=\"docutils literal notranslate\">django.contrib.postgres</code> must be in <code class=\"docutils literal notranslate\">INSTALLED_APPS</code>).</p></li>\n</ul>\n</section>\n<section id=\"django-contrib-sitemaps\">\n<h4><a class=\"reference internal\" href=\"/en/dev/ref/contrib/sitemaps/#module-django.contrib.sitemaps\" title=\"django.contrib.sitemaps: A framework for generating Google sitemap XML files.\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.sitemaps</code></a><a class=\"heading-anchor\" href=\"#django-contrib-sitemaps\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>Added the <code class=\"docutils literal notranslate\">protocol</code> keyword argument to the\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/sitemaps/#django.contrib.sitemaps.GenericSitemap\" title=\"django.contrib.sitemaps.GenericSitemap\"><code class=\"xref py py-class docutils literal notranslate\">GenericSitemap</code></a> constructor.</p></li>\n</ul>\n</section>\n<section id=\"cache\">\n<h4>Cache<a class=\"heading-anchor\" href=\"#cache\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\">cache.set_many()</code> now returns a list of keys that failed to be inserted.\nFor the built-in backends, failed inserts can only happen on memcached.</p></li>\n</ul>\n</section>\n<section id=\"file-storage\">\n<h4>File Storage<a class=\"heading-anchor\" href=\"#file-storage\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/files/file/#django.core.files.File.open\" title=\"django.core.files.File.open\"><code class=\"xref py py-meth docutils literal notranslate\">File.open()</code></a> can be used as a context\nmanager, e.g. <code class=\"docutils literal notranslate\">with file.open() as f:</code>.</p></li>\n</ul>\n</section>\n<section id=\"forms\">\n<h4>Forms<a class=\"heading-anchor\" href=\"#forms\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>The new <code class=\"docutils literal notranslate\">date_attrs</code> and <code class=\"docutils literal notranslate\">time_attrs</code> arguments for\n<a class=\"reference internal\" href=\"/en/dev/ref/forms/widgets/#django.forms.SplitDateTimeWidget\" title=\"django.forms.SplitDateTimeWidget\"><code class=\"xref py py-class docutils literal notranslate\">SplitDateTimeWidget</code></a> and\n<a class=\"reference internal\" href=\"/en/dev/ref/forms/widgets/#django.forms.SplitHiddenDateTimeWidget\" title=\"django.forms.SplitHiddenDateTimeWidget\"><code class=\"xref py py-class docutils literal notranslate\">SplitHiddenDateTimeWidget</code></a> allow specifying different\nHTML attributes for the <code class=\"docutils literal notranslate\">DateInput</code> and <code class=\"docutils literal notranslate\">TimeInput</code> (or hidden)\nsubwidgets.</p></li>\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/forms/api/#django.forms.Form.errors.get_json_data\" title=\"django.forms.Form.errors.get_json_data\"><code class=\"xref py py-meth docutils literal notranslate\">Form.errors.get_json_data()</code></a> method returns form errors as\na dictionary suitable for including in a JSON response.</p></li>\n</ul>\n</section>\n<section id=\"generic-views\">\n<h4>Generic Views<a class=\"heading-anchor\" href=\"#generic-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/class-based-views/mixins-simple/#django.views.generic.base.ContextMixin.extra_context\" title=\"django.views.generic.base.ContextMixin.extra_context\"><code class=\"xref py py-attr docutils literal notranslate\">ContextMixin.extra_context</code></a> attribute allows adding context\nin <code class=\"docutils literal notranslate\">View.as_view()</code>.</p></li>\n</ul>\n</section>\n<section id=\"management-commands\">\n<h4>Management Commands<a class=\"heading-anchor\" href=\"#management-commands\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/django-admin/#django-admin-inspectdb\"><code class=\"xref std std-djadmin docutils literal notranslate\">inspectdb</code></a> now translates MySQL’s unsigned integer columns to\n<code class=\"docutils literal notranslate\">PositiveIntegerField</code> or <code class=\"docutils literal notranslate\">PositiveSmallIntegerField</code>.</p></li>\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/django-admin/#cmdoption-makemessages-add-location\"><code class=\"xref std std-option docutils literal notranslate\">makemessages --add-location</code></a> option controls the comment\nformat in <code class=\"docutils literal notranslate\">.po</code> files.</p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/django-admin/#django-admin-loaddata\"><code class=\"xref std std-djadmin docutils literal notranslate\">loaddata</code></a> can now <a class=\"reference internal\" href=\"/en/dev/ref/django-admin/#loading-fixtures-stdin\"><span class=\"std std-ref\">read from stdin</span></a>.</p></li>\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/django-admin/#cmdoption-diffsettings-output\"><code class=\"xref std std-option docutils literal notranslate\">diffsettings --output</code></a> option allows formatting the output\nin a unified diff format.</p></li>\n<li><p>On Oracle, <a class=\"reference internal\" href=\"/en/dev/ref/django-admin/#django-admin-inspectdb\"><code class=\"xref std std-djadmin docutils literal notranslate\">inspectdb</code></a> can now introspect <code class=\"docutils literal notranslate\">AutoField</code> if the\ncolumn is created as an identity column.</p></li>\n<li><p>On MySQL, <a class=\"reference internal\" href=\"/en/dev/ref/django-admin/#django-admin-dbshell\"><code class=\"xref std std-djadmin docutils literal notranslate\">dbshell</code></a> now supports client-side TLS certificates.</p></li>\n</ul>\n</section>\n<section id=\"migrations\">\n<h4>Migrations<a class=\"heading-anchor\" href=\"#migrations\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/django-admin/#cmdoption-squashmigrations-squashed-name\"><code class=\"xref std std-option docutils literal notranslate\">squashmigrations --squashed-name</code></a> option allows naming the\nsquashed migration.</p></li>\n</ul>\n</section>\n<section id=\"models\">\n<h4>Models<a class=\"heading-anchor\" href=\"#models\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/models/database-functions/#django.db.models.functions.StrIndex\" title=\"django.db.models.functions.StrIndex\"><code class=\"xref py py-class docutils literal notranslate\">StrIndex</code></a> database function\nfinds the starting index of a string inside another string.</p></li>\n<li><p>On Oracle, <code class=\"docutils literal notranslate\">AutoField</code> and <code class=\"docutils literal notranslate\">BigAutoField</code> are now created as <a class=\"reference external\" href=\"https://docs.oracle.com/en/database/oracle/oracle-database/21/drdaa/intro-to-tools-and-products-supporting-migraiton.html#GUID-14E4817B-F3BC-4D99-B471-A0ACDC303CC9\">identity\ncolumns</a>.</p></li>\n<li><p>The new <code class=\"docutils literal notranslate\">chunk_size</code> parameter of <a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.iterator\" title=\"django.db.models.query.QuerySet.iterator\"><code class=\"xref py py-meth docutils literal notranslate\">QuerySet.iterator()</code></a> controls the\nnumber of rows fetched by the Python database client when streaming results\nfrom the database. For databases that don’t support server-side cursors, it\ncontrols the number of results Django fetches from the database adapter.</p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.earliest\" title=\"django.db.models.query.QuerySet.earliest\"><code class=\"xref py py-meth docutils literal notranslate\">QuerySet.earliest()</code></a>, <a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.latest\" title=\"django.db.models.query.QuerySet.latest\"><code class=\"xref py py-meth docutils literal notranslate\">QuerySet.latest()</code></a>, and\n<a class=\"reference internal\" href=\"/en/dev/ref/models/options/#django.db.models.Options.get_latest_by\" title=\"django.db.models.Options.get_latest_by\"><code class=\"xref py py-attr docutils literal notranslate\">Meta.get_latest_by</code></a> now\nallow ordering by several fields.</p></li>\n<li><p>Added the <a class=\"reference internal\" href=\"/en/dev/ref/models/database-functions/#django.db.models.functions.ExtractQuarter\" title=\"django.db.models.functions.ExtractQuarter\"><code class=\"xref py py-class docutils literal notranslate\">ExtractQuarter</code></a> function to\nextract the quarter from <a class=\"reference internal\" href=\"/en/dev/ref/models/fields/#django.db.models.DateField\" title=\"django.db.models.DateField\"><code class=\"xref py py-class docutils literal notranslate\">DateField</code></a> and\n<a class=\"reference internal\" href=\"/en/dev/ref/models/fields/#django.db.models.DateTimeField\" title=\"django.db.models.DateTimeField\"><code class=\"xref py py-class docutils literal notranslate\">DateTimeField</code></a>, and exposed it through the\n<a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#std-fieldlookup-quarter\"><code class=\"xref std std-lookup docutils literal notranslate\">quarter</code></a> lookup.</p></li>\n<li><p>Added the <a class=\"reference internal\" href=\"/en/dev/ref/models/database-functions/#django.db.models.functions.TruncQuarter\" title=\"django.db.models.functions.TruncQuarter\"><code class=\"xref py py-class docutils literal notranslate\">TruncQuarter</code></a> function to\ntruncate <a class=\"reference internal\" href=\"/en/dev/ref/models/fields/#django.db.models.DateField\" title=\"django.db.models.DateField\"><code class=\"xref py py-class docutils literal notranslate\">DateField</code></a> and\n<a class=\"reference internal\" href=\"/en/dev/ref/models/fields/#django.db.models.DateTimeField\" title=\"django.db.models.DateTimeField\"><code class=\"xref py py-class docutils literal notranslate\">DateTimeField</code></a> to the first day of a quarter.</p></li>\n<li><p>Added the <a class=\"reference internal\" href=\"/en/dev/ref/models/indexes/#django.db.models.Index.db_tablespace\" title=\"django.db.models.Index.db_tablespace\"><code class=\"xref py py-attr docutils literal notranslate\">db_tablespace</code></a> parameter to\nclass-based indexes.</p></li>\n<li><p>If the database supports a native duration field (Oracle and PostgreSQL),\n<a class=\"reference internal\" href=\"/en/dev/ref/models/database-functions/#django.db.models.functions.Extract\" title=\"django.db.models.functions.Extract\"><code class=\"xref py py-class docutils literal notranslate\">Extract</code></a> now works with\n<a class=\"reference internal\" href=\"/en/dev/ref/models/fields/#django.db.models.DurationField\" title=\"django.db.models.DurationField\"><code class=\"xref py py-class docutils literal notranslate\">DurationField</code></a>.</p></li>\n<li><p>Added the <code class=\"docutils literal notranslate\">of</code> argument to <a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.select_for_update\" title=\"django.db.models.query.QuerySet.select_for_update\"><code class=\"xref py py-meth docutils literal notranslate\">QuerySet.select_for_update()</code></a>, supported\non PostgreSQL and Oracle, to lock only rows from specific tables rather than\nall selected tables. It may be helpful particularly when\n<a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.select_for_update\" title=\"django.db.models.query.QuerySet.select_for_update\"><code class=\"xref py py-meth docutils literal notranslate\">select_for_update()</code></a> is used in conjunction with\n<a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.select_related\" title=\"django.db.models.query.QuerySet.select_related\"><code class=\"xref py py-meth docutils literal notranslate\">select_related()</code></a>.</p></li>\n<li><p>The new <code class=\"docutils literal notranslate\">field_name</code> parameter of <a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.in_bulk\" title=\"django.db.models.query.QuerySet.in_bulk\"><code class=\"xref py py-meth docutils literal notranslate\">QuerySet.in_bulk()</code></a> allows fetching\nresults based on any unique model field.</p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/topics/db/sql/#django.db.models.CursorWrapper.callproc\" title=\"django.db.models.CursorWrapper.callproc\"><code class=\"xref py py-meth docutils literal notranslate\">CursorWrapper.callproc()</code></a> now takes an optional dictionary of keyword\nparameters, if the backend supports this feature. Of Django’s built-in\nbackends, only Oracle supports it.</p></li>\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/topics/db/instrumentation/#django.db.connection.execute_wrapper\" title=\"django.db.connection.execute_wrapper\"><code class=\"xref py py-meth docutils literal notranslate\">connection.execute_wrapper()</code></a> method allows <a class=\"reference internal\" href=\"/en/dev/topics/db/instrumentation/\"><span class=\"doc\">installing\nwrappers around execution of database queries</span></a>.</p></li>\n<li><p>The new <code class=\"docutils literal notranslate\">filter</code> argument for built-in aggregates allows <a class=\"reference internal\" href=\"/en/dev/ref/models/conditional-expressions/#conditional-aggregation\"><span class=\"std std-ref\">adding\ndifferent conditionals</span></a> to multiple aggregations\nover the same fields or relations.</p></li>\n<li><p>Added support for expressions in <a class=\"reference internal\" href=\"/en/dev/ref/models/options/#django.db.models.Options.ordering\" title=\"django.db.models.Options.ordering\"><code class=\"xref py py-attr docutils literal notranslate\">Meta.ordering</code></a>.</p></li>\n<li><p>The new <code class=\"docutils literal notranslate\">named</code> parameter of <a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.values_list\" title=\"django.db.models.query.QuerySet.values_list\"><code class=\"xref py py-meth docutils literal notranslate\">QuerySet.values_list()</code></a> allows fetching\nresults as named tuples.</p></li>\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.FilteredRelation\" title=\"django.db.models.FilteredRelation\"><code class=\"xref py py-class docutils literal notranslate\">FilteredRelation</code></a> class allows adding an <code class=\"docutils literal notranslate\">ON</code> clause to\nquerysets.</p></li>\n</ul>\n</section>\n<section id=\"pagination\">\n<h4>Pagination<a class=\"heading-anchor\" href=\"#pagination\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>Added <a class=\"reference internal\" href=\"/en/dev/ref/paginator/#django.core.paginator.Paginator.get_page\" title=\"django.core.paginator.Paginator.get_page\"><code class=\"xref py py-meth docutils literal notranslate\">Paginator.get_page()</code></a>\nto provide the documented pattern of handling invalid page numbers.</p></li>\n</ul>\n</section>\n<section id=\"requests-and-responses\">\n<h4>Requests and Responses<a class=\"heading-anchor\" href=\"#requests-and-responses\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>The <a class=\"reference internal\" href=\"/en/dev/ref/django-admin/#django-admin-runserver\"><code class=\"xref std std-djadmin docutils literal notranslate\">runserver</code></a> web server supports HTTP 1.1.</p></li>\n</ul>\n</section>\n<section id=\"templates\">\n<h4>Templates<a class=\"heading-anchor\" href=\"#templates\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>To increase the usefulness of <a class=\"reference internal\" href=\"/en/dev/ref/templates/api/#django.template.Engine.get_default\" title=\"django.template.Engine.get_default\"><code class=\"xref py py-meth docutils literal notranslate\">Engine.get_default()</code></a> in third-party\napps, it now returns the first engine if multiple <code class=\"docutils literal notranslate\">DjangoTemplates</code> engines\nare configured in <code class=\"docutils literal notranslate\">TEMPLATES</code> rather than raising <code class=\"docutils literal notranslate\">ImproperlyConfigured</code>.</p></li>\n<li><p>Custom template tags may now accept keyword-only arguments.</p></li>\n</ul>\n</section>\n<section id=\"tests\">\n<h4>Tests<a class=\"heading-anchor\" href=\"#tests\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>Added threading support to <a class=\"reference internal\" href=\"/en/dev/topics/testing/tools/#django.test.LiveServerTestCase\" title=\"django.test.LiveServerTestCase\"><code class=\"xref py py-class docutils literal notranslate\">LiveServerTestCase</code></a>.</p></li>\n<li><p>Added settings that allow customizing the test tablespace parameters for\nOracle: <a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-DATAFILE_SIZE\"><code class=\"xref std std-setting docutils literal notranslate\">DATAFILE_SIZE</code></a>, <a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-DATAFILE_TMP_SIZE\"><code class=\"xref std std-setting docutils literal notranslate\">DATAFILE_TMP_SIZE</code></a>,\n<a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-DATAFILE_EXTSIZE\"><code class=\"xref std std-setting docutils literal notranslate\">DATAFILE_EXTSIZE</code></a>, and <a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-DATAFILE_TMP_EXTSIZE\"><code class=\"xref std std-setting docutils literal notranslate\">DATAFILE_TMP_EXTSIZE</code></a>.</p></li>\n</ul>\n</section>\n<section id=\"validators\">\n<h4>Validators<a class=\"heading-anchor\" href=\"#validators\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/validators/#django.core.validators.ProhibitNullCharactersValidator\" title=\"django.core.validators.ProhibitNullCharactersValidator\"><code class=\"xref py py-class docutils literal notranslate\">ProhibitNullCharactersValidator</code></a> disallows the null\ncharacter in the input of the <a class=\"reference internal\" href=\"/en/dev/ref/forms/fields/#django.forms.CharField\" title=\"django.forms.CharField\"><code class=\"xref py py-class docutils literal notranslate\">CharField</code></a> form field\nand its subclasses. Null character input was observed from vulnerability\nscanning tools. Most databases silently discard null characters, but\npsycopg2 2.7+ raises an exception when trying to save a null character to\na char/text field with PostgreSQL.</p></li>\n</ul>\n</section>\n</section>\n</section>\n<section id=\"backwards-incompatible-changes-in-2-0\">\n<span id=\"backwards-incompatible-2-0\"></span><h2>Backwards incompatible changes in 2.0<a class=\"heading-anchor\" href=\"#backwards-incompatible-changes-in-2-0\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"removed-support-for-bytestrings-in-some-places\">\n<h3>Removed support for bytestrings in some places<a class=\"heading-anchor\" href=\"#removed-support-for-bytestrings-in-some-places\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>To support native Python 2 strings, older Django versions had to accept both\nbytestrings and Unicode strings. Now that Python 2 support is dropped,\nbytestrings should only be encountered around input/output boundaries (handling\nof binary fields or HTTP streams, for example). You might have to update your\ncode to limit bytestring usage to a minimum, as Django no longer accepts\nbytestrings in certain code paths. Python’s <a class=\"reference external\" href=\"https://docs.python.org/3/using/cmdline.html#cmdoption-b\" title=\"(in Python v3.14)\"><code class=\"xref std std-option docutils literal notranslate\">-b</code></a> option may help detect\nthat mistake in your code.</p>\n<p>For example, <code class=\"docutils literal notranslate\">reverse()</code> now uses <code class=\"docutils literal notranslate\">str()</code> instead of <code class=\"docutils literal notranslate\">force_text()</code> to\ncoerce the <code class=\"docutils literal notranslate\">args</code> and <code class=\"docutils literal notranslate\">kwargs</code> it receives, prior to their placement in\nthe URL. For bytestrings, this creates a string with an undesired <code class=\"docutils literal notranslate\">b</code> prefix\nas well as additional quotes (<code class=\"docutils literal notranslate\">str(b'foo')</code> is <code class=\"docutils literal notranslate\">&quot;b'foo'&quot;</code>). To adapt, call\n<code class=\"docutils literal notranslate\">decode()</code> on the bytestring before passing it to <code class=\"docutils literal notranslate\">reverse()</code>.</p>\n</section>\n<section id=\"database-backend-api\">\n<h3>Database backend API<a class=\"heading-anchor\" href=\"#database-backend-api\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>This section describes changes that may be needed in third-party database\nbackends.</p>\n<ul class=\"simple\">\n<li><p>The <code class=\"docutils literal notranslate\">DatabaseOperations.datetime_cast_date_sql()</code>,\n<code class=\"docutils literal notranslate\">datetime_cast_time_sql()</code>, <code class=\"docutils literal notranslate\">datetime_trunc_sql()</code>,\n<code class=\"docutils literal notranslate\">datetime_extract_sql()</code>, and <code class=\"docutils literal notranslate\">date_interval_sql()</code> methods now return\nonly the SQL to perform the operation instead of SQL and a list of\nparameters.</p></li>\n<li><p>Third-party database backends should add a <code class=\"docutils literal notranslate\">DatabaseWrapper.display_name</code>\nattribute with the name of the database that your backend works with. Django\nmay use it in various messages, such as in system checks.</p></li>\n<li><p>The first argument of <code class=\"docutils literal notranslate\">SchemaEditor._alter_column_type_sql()</code> is now\n<code class=\"docutils literal notranslate\">model</code> rather than <code class=\"docutils literal notranslate\">table</code>.</p></li>\n<li><p>The first argument of <code class=\"docutils literal notranslate\">SchemaEditor._create_index_name()</code> is now\n<code class=\"docutils literal notranslate\">table_name</code> rather than <code class=\"docutils literal notranslate\">model</code>.</p></li>\n<li><p>To enable <code class=\"docutils literal notranslate\">FOR UPDATE OF</code> support, set\n<code class=\"docutils literal notranslate\">DatabaseFeatures.has_select_for_update_of = True</code>. If the database\nrequires that the arguments to <code class=\"docutils literal notranslate\">OF</code> be columns rather than tables, set\n<code class=\"docutils literal notranslate\">DatabaseFeatures.select_for_update_of_column = True</code>.</p></li>\n<li><p>To enable support for <a class=\"reference internal\" href=\"/en/dev/ref/models/expressions/#django.db.models.expressions.Window\" title=\"django.db.models.expressions.Window\"><code class=\"xref py py-class docutils literal notranslate\">Window</code></a>\nexpressions, set <code class=\"docutils literal notranslate\">DatabaseFeatures.supports_over_clause</code> to <code class=\"docutils literal notranslate\">True</code>. You\nmay need to customize the\n<code class=\"docutils literal notranslate\">DatabaseOperations.window_start_rows_start_end()</code> and/or\n<code class=\"docutils literal notranslate\">window_start_range_start_end()</code> methods.</p></li>\n<li><p>Third-party database backends should add a\n<code class=\"docutils literal notranslate\">DatabaseOperations.cast_char_field_without_max_length</code> attribute with the\ndatabase data type that will be used in the\n<a class=\"reference internal\" href=\"/en/dev/ref/models/database-functions/#django.db.models.functions.Cast\" title=\"django.db.models.functions.Cast\"><code class=\"xref py py-class docutils literal notranslate\">Cast</code></a> function for a <code class=\"docutils literal notranslate\">CharField</code> if the\n<code class=\"docutils literal notranslate\">max_length</code> argument isn’t provided.</p></li>\n<li><p>The first argument of <code class=\"docutils literal notranslate\">DatabaseCreation._clone_test_db()</code> and\n<code class=\"docutils literal notranslate\">get_test_db_clone_settings()</code> is now <code class=\"docutils literal notranslate\">suffix</code> rather\nthan <code class=\"docutils literal notranslate\">number</code> (in case you want to rename the signatures in your backend\nfor consistency). <code class=\"docutils literal notranslate\">django.test</code> also now passes those values as strings\nrather than as integers.</p></li>\n<li><p>Third-party database backends should add a\n<code class=\"docutils literal notranslate\">DatabaseIntrospection.get_sequences()</code> method based on the stub in\n<code class=\"docutils literal notranslate\">BaseDatabaseIntrospection</code>.</p></li>\n</ul>\n</section>\n<section id=\"dropped-support-for-oracle-11-2\">\n<h3>Dropped support for Oracle 11.2<a class=\"heading-anchor\" href=\"#dropped-support-for-oracle-11-2\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The end of upstream support for Oracle 11.2 is Dec. 2020. Django 1.11 will be\nsupported until April 2020 which almost reaches this date. Django 2.0\nofficially supports Oracle 12.1+.</p>\n</section>\n<section id=\"default-mysql-isolation-level-is-read-committed\">\n<h3>Default MySQL isolation level is read committed<a class=\"heading-anchor\" href=\"#default-mysql-isolation-level-is-read-committed\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>MySQL’s default isolation level, repeatable read, may cause data loss in\ntypical Django usage. To prevent that and for consistency with other databases,\nthe default isolation level is now read committed. You can use the\n<a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-DATABASES\"><code class=\"xref std std-setting docutils literal notranslate\">DATABASES</code></a> setting to <a class=\"reference internal\" href=\"/en/dev/ref/databases/#mysql-isolation-level\"><span class=\"std std-ref\">use a different isolation level</span></a>, if needed.</p>\n</section>\n<section id=\"abstractuser-last-name-max-length-increased-to-150\">\n<h3><a class=\"reference internal\" href=\"/en/dev/ref/contrib/auth/#django.contrib.auth.models.User.last_name\" title=\"django.contrib.auth.models.User.last_name\"><code class=\"xref py py-attr docutils literal notranslate\">AbstractUser.last_name</code></a> <code class=\"docutils literal notranslate\">max_length</code> increased to 150<a class=\"heading-anchor\" href=\"#abstractuser-last-name-max-length-increased-to-150\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>A migration for <a class=\"reference internal\" href=\"/en/dev/ref/contrib/auth/#django.contrib.auth.models.User.last_name\" title=\"django.contrib.auth.models.User.last_name\"><code class=\"xref py py-attr docutils literal notranslate\">django.contrib.auth.models.User.last_name</code></a> is included.\nIf you have a custom user model inheriting from <code class=\"docutils literal notranslate\">AbstractUser</code>, you’ll need\nto generate and apply a database migration for your user model.</p>\n<p>If you want to preserve the 30 character limit for last names, use a custom\nform:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.contrib.auth.forms</span> <span class=\"kn\">import</span> UserChangeForm\n\n\n<span class=\"k\">class</span> <span class=\"nc\">MyUserChangeForm</span><span class=\"p\">(</span>UserChangeForm<span class=\"p\">):</span>\n    last_name <span class=\"o\">=</span> forms<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">30</span><span class=\"p\">,</span> required<span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>If you wish to keep this restriction in the admin when editing users, set\n<code class=\"docutils literal notranslate\">UserAdmin.form</code> to use this form:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.contrib.auth.admin</span> <span class=\"kn\">import</span> UserAdmin\n<span class=\"kn\">from</span> <span class=\"nn\">django.contrib.auth.models</span> <span class=\"kn\">import</span> User\n\n\n<span class=\"k\">class</span> <span class=\"nc\">MyUserAdmin</span><span class=\"p\">(</span>UserAdmin<span class=\"p\">):</span>\n    form <span class=\"o\">=</span> MyUserChangeForm\n\n\nadmin<span class=\"o\">.</span>site<span class=\"o\">.</span>unregister<span class=\"p\">(</span>User<span class=\"p\">)</span>\nadmin<span class=\"o\">.</span>site<span class=\"o\">.</span>register<span class=\"p\">(</span>User<span class=\"p\">,</span> MyUserAdmin<span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"queryset-reverse-and-last-are-prohibited-after-slicing\">\n<h3><code class=\"docutils literal notranslate\">QuerySet.reverse()</code> and <code class=\"docutils literal notranslate\">last()</code> are prohibited after slicing<a class=\"heading-anchor\" href=\"#queryset-reverse-and-last-are-prohibited-after-slicing\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Calling <code class=\"docutils literal notranslate\">QuerySet.reverse()</code> or <code class=\"docutils literal notranslate\">last()</code> on a sliced queryset leads to\nunexpected results due to the slice being applied after reordering. This is\nnow prohibited, e.g.:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>Model<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">()[:</span><span class=\"mi\">2</span><span class=\"p\">]</span><span class=\"o\">.</span>reverse<span class=\"p\">()</span>\n<span class=\"gt\">Traceback (most recent call last):</span>\n<span class=\"c\">...</span>\n<span class=\"gr\">TypeError</span>: Cannot reverse a query once a slice has been taken.\n</code></pre></div>\n</section>\n<section id=\"form-fields-no-longer-accept-optional-arguments-as-positional-arguments\">\n<h3>Form fields no longer accept optional arguments as positional arguments<a class=\"heading-anchor\" href=\"#form-fields-no-longer-accept-optional-arguments-as-positional-arguments\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>To help prevent runtime errors due to incorrect ordering of form field\narguments, optional arguments of built-in form fields are no longer accepted\nas positional arguments. For example:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>forms<span class=\"o\">.</span>IntegerField<span class=\"p\">(</span><span class=\"mi\">25</span><span class=\"p\">,</span> <span class=\"mi\">10</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>raises an exception and should be replaced with:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>forms<span class=\"o\">.</span>IntegerField<span class=\"p\">(</span>max_value<span class=\"o\">=</span><span class=\"mi\">25</span><span class=\"p\">,</span> min_value<span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"call-command-validates-the-options-it-receives\">\n<h3><code class=\"docutils literal notranslate\">call_command()</code> validates the options it receives<a class=\"heading-anchor\" href=\"#call-command-validates-the-options-it-receives\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><code class=\"docutils literal notranslate\">call_command()</code> now validates that the argument parser of the command being\ncalled defines all of the options passed to <code class=\"docutils literal notranslate\">call_command()</code>.</p>\n<p>For custom management commands that use options not created using\n<code class=\"docutils literal notranslate\">parser.add_argument()</code>, add a <code class=\"docutils literal notranslate\">stealth_options</code> attribute on the command:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">MyCommand</span><span class=\"p\">(</span>BaseCommand<span class=\"p\">):</span>\n    stealth_options <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"s2\">&quot;option_name&quot;</span><span class=\"p\">,</span> <span class=\"o\">...</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"indexes-no-longer-accept-positional-arguments\">\n<h3>Indexes no longer accept positional arguments<a class=\"heading-anchor\" href=\"#indexes-no-longer-accept-positional-arguments\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>For example:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>models<span class=\"o\">.</span>Index<span class=\"p\">([</span><span class=\"s2\">&quot;headline&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;-pub_date&quot;</span><span class=\"p\">],</span> <span class=\"s2\">&quot;index_name&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>raises an exception and should be replaced with:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>models<span class=\"o\">.</span>Index<span class=\"p\">(</span>fields<span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s2\">&quot;headline&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;-pub_date&quot;</span><span class=\"p\">],</span> name<span class=\"o\">=</span><span class=\"s2\">&quot;index_name&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"foreign-key-constraints-are-now-enabled-on-sqlite\">\n<h3>Foreign key constraints are now enabled on SQLite<a class=\"heading-anchor\" href=\"#foreign-key-constraints-are-now-enabled-on-sqlite\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>This will appear as a backwards-incompatible change (<code class=\"docutils literal notranslate\">IntegrityError:\nFOREIGN KEY constraint failed</code>) if attempting to save an existing model\ninstance that’s violating a foreign key constraint.</p>\n<p>Foreign keys are now created with <code class=\"docutils literal notranslate\">DEFERRABLE INITIALLY DEFERRED</code> instead of\n<code class=\"docutils literal notranslate\">DEFERRABLE IMMEDIATE</code>. Thus, tables may need to be rebuilt to recreate\nforeign keys with the new definition, particularly if you’re using a pattern\nlike this:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> transaction\n\n<span class=\"k\">with</span> transaction<span class=\"o\">.</span>atomic<span class=\"p\">():</span>\n    Book<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>author_id<span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n    Author<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>If you don’t recreate the foreign key as <code class=\"docutils literal notranslate\">DEFERRED</code>, the first <code class=\"docutils literal notranslate\">create()</code>\nwould fail now that foreign key constraints are enforced.</p>\n<p>Backup your database first! After upgrading to Django 2.0, you can then\nrebuild tables using a script similar to this:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.apps</span> <span class=\"kn\">import</span> apps\n<span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> connection\n\n<span class=\"k\">for</span> app <span class=\"ow\">in</span> apps<span class=\"o\">.</span>get_app_configs<span class=\"p\">():</span>\n    <span class=\"k\">for</span> model <span class=\"ow\">in</span> app<span class=\"o\">.</span>get_models<span class=\"p\">(</span>include_auto_created<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> model<span class=\"o\">.</span>_meta<span class=\"o\">.</span>managed <span class=\"ow\">and</span> <span class=\"ow\">not</span> <span class=\"p\">(</span>model<span class=\"o\">.</span>_meta<span class=\"o\">.</span>proxy <span class=\"ow\">or</span> model<span class=\"o\">.</span>_meta<span class=\"o\">.</span>swapped<span class=\"p\">):</span>\n            <span class=\"k\">for</span> base <span class=\"ow\">in</span> model<span class=\"o\">.</span><span class=\"vm\">__bases__</span><span class=\"p\">:</span>\n                <span class=\"k\">if</span> <span class=\"nb\">hasattr</span><span class=\"p\">(</span>base<span class=\"p\">,</span> <span class=\"s2\">&quot;_meta&quot;</span><span class=\"p\">):</span>\n                    base<span class=\"o\">.</span>_meta<span class=\"o\">.</span>local_many_to_many <span class=\"o\">=</span> <span class=\"p\">[]</span>\n            model<span class=\"o\">.</span>_meta<span class=\"o\">.</span>local_many_to_many <span class=\"o\">=</span> <span class=\"p\">[]</span>\n            <span class=\"k\">with</span> connection<span class=\"o\">.</span>schema_editor<span class=\"p\">()</span> <span class=\"k\">as</span> editor<span class=\"p\">:</span>\n                editor<span class=\"o\">.</span>_remake_table<span class=\"p\">(</span>model<span class=\"p\">)</span>\n</code></pre></div>\n<p>This script hasn’t received extensive testing and needs adaption for various\ncases such as multiple databases. Feel free to contribute improvements.</p>\n<p>In addition, because of a table alteration limitation of SQLite, it’s\nprohibited to perform <a class=\"reference internal\" href=\"/en/dev/ref/migration-operations/#django.db.migrations.operations.RenameModel\" title=\"django.db.migrations.operations.RenameModel\"><code class=\"xref py py-class docutils literal notranslate\">RenameModel</code></a> and\n<a class=\"reference internal\" href=\"/en/dev/ref/migration-operations/#django.db.migrations.operations.RenameField\" title=\"django.db.migrations.operations.RenameField\"><code class=\"xref py py-class docutils literal notranslate\">RenameField</code></a> operations on models or\nfields referenced by other models in a transaction. In order to allow\nmigrations containing these operations to be applied, you must set the\n<code class=\"docutils literal notranslate\">Migration.atomic</code> attribute to <code class=\"docutils literal notranslate\">False</code>.</p>\n</section>\n<section id=\"miscellaneous\">\n<h3>Miscellaneous<a class=\"heading-anchor\" href=\"#miscellaneous\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<ul>\n<li><p>The <code class=\"docutils literal notranslate\">SessionAuthenticationMiddleware</code> class is removed. It provided no\nfunctionality since session authentication is unconditionally enabled in\nDjango 1.10.</p></li>\n<li><p>The default HTTP error handlers (<code class=\"docutils literal notranslate\">handler404</code>, etc.) are now callables\ninstead of dotted Python path strings. Django favors callable references\nsince they provide better performance and debugging experience.</p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/class-based-views/base/#django.views.generic.base.RedirectView\" title=\"django.views.generic.base.RedirectView\"><code class=\"xref py py-class docutils literal notranslate\">RedirectView</code></a> no longer silences\n<code class=\"docutils literal notranslate\">NoReverseMatch</code> if the <code class=\"docutils literal notranslate\">pattern_name</code> doesn’t exist.</p></li>\n<li><p>When <code class=\"docutils literal notranslate\">USE_L10N</code> is off, <a class=\"reference internal\" href=\"/en/dev/ref/forms/fields/#django.forms.FloatField\" title=\"django.forms.FloatField\"><code class=\"xref py py-class docutils literal notranslate\">FloatField</code></a> and\n<a class=\"reference internal\" href=\"/en/dev/ref/forms/fields/#django.forms.DecimalField\" title=\"django.forms.DecimalField\"><code class=\"xref py py-class docutils literal notranslate\">DecimalField</code></a> now respect <a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-DECIMAL_SEPARATOR\"><code class=\"xref std std-setting docutils literal notranslate\">DECIMAL_SEPARATOR</code></a>\nand <a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-THOUSAND_SEPARATOR\"><code class=\"xref std std-setting docutils literal notranslate\">THOUSAND_SEPARATOR</code></a> during validation. For example, with the\nsettings:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>USE_L10N <span class=\"o\">=</span> <span class=\"kc\">False</span>\nUSE_THOUSAND_SEPARATOR <span class=\"o\">=</span> <span class=\"kc\">True</span>\nDECIMAL_SEPARATOR <span class=\"o\">=</span> <span class=\"s2\">&quot;,&quot;</span>\nTHOUSAND_SEPARATOR <span class=\"o\">=</span> <span class=\"s2\">&quot;.&quot;</span>\n</code></pre></div>\n<p>an input of <code class=\"docutils literal notranslate\">&quot;1.345&quot;</code> is now converted to <code class=\"docutils literal notranslate\">1345</code> instead of <code class=\"docutils literal notranslate\">1.345</code>.</p>\n</li>\n<li><p>Subclasses of <a class=\"reference internal\" href=\"/en/dev/topics/auth/customizing/#django.contrib.auth.models.AbstractBaseUser\" title=\"django.contrib.auth.models.AbstractBaseUser\"><code class=\"xref py py-class docutils literal notranslate\">AbstractBaseUser</code></a> are no\nlonger required to implement <code class=\"docutils literal notranslate\">get_short_name()</code> and <code class=\"docutils literal notranslate\">get_full_name()</code>.\n(The base implementations that raise <code class=\"docutils literal notranslate\">NotImplementedError</code> are removed.)\n<code class=\"docutils literal notranslate\">django.contrib.admin</code> uses these methods if implemented but doesn’t\nrequire them. Third-party apps that use these methods may want to adopt a\nsimilar approach.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">FIRST_DAY_OF_WEEK</code> and <code class=\"docutils literal notranslate\">NUMBER_GROUPING</code> format settings are now\nkept as integers in JavaScript and JSON i18n view outputs.</p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/topics/testing/tools/#django.test.TransactionTestCase.assertNumQueries\" title=\"django.test.TransactionTestCase.assertNumQueries\"><code class=\"xref py py-meth docutils literal notranslate\">assertNumQueries()</code></a> now ignores\nconnection configuration queries. Previously, if a test opened a new database\nconnection, those queries could be included as part of the\n<code class=\"docutils literal notranslate\">assertNumQueries()</code> count.</p></li>\n<li><p>The default size of the Oracle test tablespace is increased from 20M to 50M\nand the default autoextend size is increased from 10M to 25M.</p></li>\n<li><p>To improve performance when streaming large result sets from the database,\n<a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.iterator\" title=\"django.db.models.query.QuerySet.iterator\"><code class=\"xref py py-meth docutils literal notranslate\">QuerySet.iterator()</code></a> now fetches 2000 rows at a time instead of 100.\nThe old behavior can be restored using the <code class=\"docutils literal notranslate\">chunk_size</code> parameter. For\nexample:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>Book<span class=\"o\">.</span>objects<span class=\"o\">.</span>iterator<span class=\"p\">(</span>chunk_size<span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n</code></pre></div>\n</li>\n<li><p>Providing unknown package names in the <code class=\"docutils literal notranslate\">packages</code> argument of the\n<a class=\"reference internal\" href=\"/en/dev/topics/i18n/translation/#django.views.i18n.JavaScriptCatalog\" title=\"django.views.i18n.JavaScriptCatalog\"><code class=\"xref py py-class docutils literal notranslate\">JavaScriptCatalog</code></a> view now raises <code class=\"docutils literal notranslate\">ValueError</code>\ninstead of passing silently.</p></li>\n<li><p>A model instance’s primary key now appears in the default <code class=\"docutils literal notranslate\">Model.__str__()</code>\nmethod, e.g. <code class=\"docutils literal notranslate\">Question object (1)</code>.</p></li>\n<li><p><code class=\"docutils literal notranslate\">makemigrations</code> now detects changes to the model field <code class=\"docutils literal notranslate\">limit_choices_to</code>\noption. Add this to your existing migrations or accept an auto-generated\nmigration for fields that use it.</p></li>\n<li><p>Performing queries that require <a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/tutorial/#automatic-spatial-transformations\"><span class=\"std std-ref\">automatic spatial transformations</span></a> now raises <code class=\"docutils literal notranslate\">NotImplementedError</code>\non MySQL instead of silently using non-transformed geometries.</p></li>\n<li><p><code class=\"docutils literal notranslate\">django.core.exceptions.DjangoRuntimeWarning</code> is removed. It was only used\nin the cache backend as an intermediate class in <code class=\"docutils literal notranslate\">CacheKeyWarning</code>’s\ninheritance of <code class=\"docutils literal notranslate\">RuntimeWarning</code>.</p></li>\n<li><p>Renamed <code class=\"docutils literal notranslate\">BaseExpression._output_field</code> to <code class=\"docutils literal notranslate\">output_field</code>. You may need\nto update custom expressions.</p></li>\n<li><p>In older versions, forms and formsets combine their <code class=\"docutils literal notranslate\">Media</code> with widget\n<code class=\"docutils literal notranslate\">Media</code> by concatenating the two. The combining now tries to <a class=\"reference internal\" href=\"/en/dev/topics/forms/media/#form-media-asset-order\"><span class=\"std std-ref\">preserve\nthe relative order of elements in each list</span></a>.\n<code class=\"docutils literal notranslate\">MediaOrderConflictWarning</code> is issued if the order can’t be preserved.</p></li>\n<li><p><code class=\"docutils literal notranslate\">django.contrib.gis.gdal.OGRException</code> is removed. It’s been an alias for\n<code class=\"docutils literal notranslate\">GDALException</code> since Django 1.8.</p></li>\n<li><p>Support for GEOS 3.3.x is dropped.</p></li>\n<li><p>The way data is selected for <code class=\"docutils literal notranslate\">GeometryField</code> is changed to improve\nperformance, and in raw SQL queries, those fields must now be wrapped in\n<code class=\"docutils literal notranslate\">connection.ops.select</code>. See the <a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/tutorial/#gis-raw-sql\"><span class=\"std std-ref\">Raw queries note</span></a> in\nthe GIS tutorial for an example.</p></li>\n</ul>\n</section>\n</section>\n<section id=\"features-deprecated-in-2-0\">\n<span id=\"deprecated-features-2-0\"></span><h2>Features deprecated in 2.0<a class=\"heading-anchor\" href=\"#features-deprecated-in-2-0\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"context-argument-of-field-from-db-value-and-expression-convert-value\">\n<h3><code class=\"docutils literal notranslate\">context</code> argument of <code class=\"docutils literal notranslate\">Field.from_db_value()</code> and <code class=\"docutils literal notranslate\">Expression.convert_value()</code><a class=\"heading-anchor\" href=\"#context-argument-of-field-from-db-value-and-expression-convert-value\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The <code class=\"docutils literal notranslate\">context</code> argument of <code class=\"docutils literal notranslate\">Field.from_db_value()</code> and\n<code class=\"docutils literal notranslate\">Expression.convert_value()</code> is unused as it’s always an empty dictionary.\nThe signature of both methods is now:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> value<span class=\"p\">,</span> expression<span class=\"p\">,</span> connection<span class=\"p\">)</span>\n</code></pre></div>\n<p>instead of:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> value<span class=\"p\">,</span> expression<span class=\"p\">,</span> connection<span class=\"p\">,</span> context<span class=\"p\">)</span>\n</code></pre></div>\n<p>Support for the old signature in custom fields and expressions remains until\nDjango 3.0.</p>\n</section>\n<section id=\"id1\">\n<h3>Miscellaneous<a class=\"heading-anchor\" href=\"#id1\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<ul class=\"simple\">\n<li><p>The <code class=\"docutils literal notranslate\">django.db.backends.postgresql_psycopg2</code> module is deprecated in favor\nof <code class=\"docutils literal notranslate\">django.db.backends.postgresql</code>. It’s been an alias since Django 1.9.\nThis only affects code that imports from the module directly. The\n<code class=\"docutils literal notranslate\">DATABASES</code> setting can still use\n<code class=\"docutils literal notranslate\">'django.db.backends.postgresql_psycopg2'</code>, though you can simplify that by\nusing the <code class=\"docutils literal notranslate\">'django.db.backends.postgresql'</code> name added in Django 1.9.</p></li>\n<li><p><code class=\"docutils literal notranslate\">django.shortcuts.render_to_response()</code> is deprecated in favor of\n<a class=\"reference internal\" href=\"/en/dev/topics/http/shortcuts/#django.shortcuts.render\" title=\"django.shortcuts.render\"><code class=\"xref py py-func docutils literal notranslate\">django.shortcuts.render()</code></a>. <code class=\"docutils literal notranslate\">render()</code> takes the same arguments\nexcept that it also requires a <code class=\"docutils literal notranslate\">request</code>.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">DEFAULT_CONTENT_TYPE</code> setting is deprecated. It doesn’t interact well\nwith third-party apps and is obsolete since HTML5 has mostly superseded\nXHTML.</p></li>\n<li><p><code class=\"docutils literal notranslate\">HttpRequest.xreadlines()</code> is deprecated in favor of iterating over the\nrequest.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">field_name</code> keyword argument to <a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.earliest\" title=\"django.db.models.query.QuerySet.earliest\"><code class=\"xref py py-meth docutils literal notranslate\">QuerySet.earliest()</code></a> and\n<a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.latest\" title=\"django.db.models.query.QuerySet.latest\"><code class=\"xref py py-meth docutils literal notranslate\">QuerySet.latest()</code></a> is deprecated in favor of passing the field\nnames as arguments. Write <code class=\"docutils literal notranslate\">.earliest('pub_date')</code> instead of\n<code class=\"docutils literal notranslate\">.earliest(field_name='pub_date')</code>.</p></li>\n</ul>\n</section>\n</section>\n<section id=\"features-removed-in-2-0\">\n<span id=\"removed-features-2-0\"></span><h2>Features removed in 2.0<a class=\"heading-anchor\" href=\"#features-removed-in-2-0\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>These features have reached the end of their deprecation cycle and are removed\nin Django 2.0.</p>\n<p>See <a class=\"reference internal\" href=\"/en/dev/releases/1.9/#deprecated-features-1-9\"><span class=\"std std-ref\">Features deprecated in 1.9</span></a> for details on these changes, including how\nto remove usage of these features.</p>\n<ul class=\"simple\">\n<li><p>The <code class=\"docutils literal notranslate\">weak</code> argument to <code class=\"docutils literal notranslate\">django.dispatch.signals.Signal.disconnect()</code> is\nremoved.</p></li>\n<li><p><code class=\"docutils literal notranslate\">django.db.backends.base.BaseDatabaseOperations.check_aggregate_support()</code>\nis removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">django.forms.extras</code> package is removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">assignment_tag</code> helper is removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">host</code> argument to <code class=\"docutils literal notranslate\">SimpleTestCase.assertsRedirects()</code> is removed.\nThe compatibility layer which allows absolute URLs to be considered equal to\nrelative ones when the path is identical is also removed.</p></li>\n<li><p><code class=\"docutils literal notranslate\">Field.rel</code> and <code class=\"docutils literal notranslate\">Field.remote_field.to</code> are removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">on_delete</code> argument for <code class=\"docutils literal notranslate\">ForeignKey</code> and <code class=\"docutils literal notranslate\">OneToOneField</code> is now\nrequired in models and migrations. Consider squashing migrations so that you\nhave fewer of them to update.</p></li>\n<li><p><code class=\"docutils literal notranslate\">django.db.models.fields.add_lazy_relation()</code> is removed.</p></li>\n<li><p>When time zone support is enabled, database backends that don’t support time\nzones no longer convert aware datetimes to naive values in UTC anymore when\nsuch values are passed as parameters to SQL queries executed outside of the\nORM, e.g. with <code class=\"docutils literal notranslate\">cursor.execute()</code>.</p></li>\n<li><p><code class=\"docutils literal notranslate\">django.contrib.auth.tests.utils.skipIfCustomUser()</code> is removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">GeoManager</code> and <code class=\"docutils literal notranslate\">GeoQuerySet</code> classes are removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">django.contrib.gis.geoip</code> module is removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">supports_recursion</code> check for template loaders is removed from:</p>\n<ul>\n<li><p><code class=\"docutils literal notranslate\">django.template.engine.Engine.find_template()</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">django.template.loader_tags.ExtendsNode.find_template()</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">django.template.loaders.base.Loader.supports_recursion()</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">django.template.loaders.cached.Loader.supports_recursion()</code></p></li>\n</ul>\n</li>\n<li><p>The <code class=\"docutils literal notranslate\">load_template</code> and <code class=\"docutils literal notranslate\">load_template_sources</code> template loader methods\nare removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">template_dirs</code> argument for template loaders is removed:</p>\n<ul>\n<li><p><code class=\"docutils literal notranslate\">django.template.loaders.base.Loader.get_template()</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">django.template.loaders.cached.Loader.cache_key()</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">django.template.loaders.cached.Loader.get_template()</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">django.template.loaders.cached.Loader.get_template_sources()</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">django.template.loaders.filesystem.Loader.get_template_sources()</code></p></li>\n</ul>\n</li>\n<li><p><code class=\"docutils literal notranslate\">django.template.loaders.base.Loader.__call__()</code> is removed.</p></li>\n<li><p>Support for custom error views that don’t accept an <code class=\"docutils literal notranslate\">exception</code> parameter\nis removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">mime_type</code> attribute of <code class=\"docutils literal notranslate\">django.utils.feedgenerator.Atom1Feed</code> and\n<code class=\"docutils literal notranslate\">django.utils.feedgenerator.RssFeed</code> is removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">app_name</code> argument to <code class=\"docutils literal notranslate\">include()</code> is removed.</p></li>\n<li><p>Support for passing a 3-tuple (including <code class=\"docutils literal notranslate\">admin.site.urls</code>) as the first\nargument to <code class=\"docutils literal notranslate\">include()</code> is removed.</p></li>\n<li><p>Support for setting a URL instance namespace without an application namespace\nis removed.</p></li>\n<li><p><code class=\"docutils literal notranslate\">Field._get_val_from_obj()</code> is removed.</p></li>\n<li><p><code class=\"docutils literal notranslate\">django.template.loaders.eggs.Loader</code> is removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">current_app</code> parameter to the <code class=\"docutils literal notranslate\">contrib.auth</code> function-based views is\nremoved.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">callable_obj</code> keyword argument to\n<code class=\"docutils literal notranslate\">SimpleTestCase.assertRaisesMessage()</code> is removed.</p></li>\n<li><p>Support for the <code class=\"docutils literal notranslate\">allow_tags</code> attribute on <code class=\"docutils literal notranslate\">ModelAdmin</code> methods is\nremoved.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">enclosure</code> keyword argument to <code class=\"docutils literal notranslate\">SyndicationFeed.add_item()</code> is\nremoved.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">django.template.loader.LoaderOrigin</code> and\n<code class=\"docutils literal notranslate\">django.template.base.StringOrigin</code> aliases for\n<code class=\"docutils literal notranslate\">django.template.base.Origin</code> are removed.</p></li>\n</ul>\n<p>See <a class=\"reference internal\" href=\"/en/dev/releases/1.10/#deprecated-features-1-10\"><span class=\"std std-ref\">Features deprecated in 1.10</span></a> for details on these changes.</p>\n<ul class=\"simple\">\n<li><p>The <code class=\"docutils literal notranslate\">makemigrations --exit</code> option is removed.</p></li>\n<li><p>Support for direct assignment to a reverse foreign key or many-to-many\nrelation is removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">get_srid()</code> and <code class=\"docutils literal notranslate\">set_srid()</code> methods of\n<code class=\"docutils literal notranslate\">django.contrib.gis.geos.GEOSGeometry</code> are removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">get_x()</code>, <code class=\"docutils literal notranslate\">set_x()</code>, <code class=\"docutils literal notranslate\">get_y()</code>, <code class=\"docutils literal notranslate\">set_y()</code>, <code class=\"docutils literal notranslate\">get_z()</code>, and\n<code class=\"docutils literal notranslate\">set_z()</code> methods of <code class=\"docutils literal notranslate\">django.contrib.gis.geos.Point</code> are removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">get_coords()</code> and <code class=\"docutils literal notranslate\">set_coords()</code> methods of\n<code class=\"docutils literal notranslate\">django.contrib.gis.geos.Point</code> are removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">cascaded_union</code> property of <code class=\"docutils literal notranslate\">django.contrib.gis.geos.MultiPolygon</code>\nis removed.</p></li>\n<li><p><code class=\"docutils literal notranslate\">django.utils.functional.allow_lazy()</code> is removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">shell --plain</code> option is removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">django.core.urlresolvers</code> module is removed in favor of its new\nlocation, <code class=\"docutils literal notranslate\">django.urls</code>.</p></li>\n<li><p><code class=\"docutils literal notranslate\">CommaSeparatedIntegerField</code> is removed, except for support in historical\nmigrations.</p></li>\n<li><p>The template <code class=\"docutils literal notranslate\">Context.has_key()</code> method is removed.</p></li>\n<li><p>Support for the <code class=\"docutils literal notranslate\">django.core.files.storage.Storage.accessed_time()</code>,\n<code class=\"docutils literal notranslate\">created_time()</code>, and <code class=\"docutils literal notranslate\">modified_time()</code> methods is removed.</p></li>\n<li><p>Support for query lookups using the model name when\n<code class=\"docutils literal notranslate\">Meta.default_related_name</code> is set is removed.</p></li>\n<li><p>The MySQL <code class=\"docutils literal notranslate\">__search</code> lookup is removed.</p></li>\n<li><p>The shim for supporting custom related manager classes without a\n<code class=\"docutils literal notranslate\">_apply_rel_filters()</code> method is removed.</p></li>\n<li><p>Using <code class=\"docutils literal notranslate\">User.is_authenticated()</code> and <code class=\"docutils literal notranslate\">User.is_anonymous()</code> as methods\nrather than properties is no longer supported.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">Model._meta.virtual_fields</code> attribute is removed.</p></li>\n<li><p>The keyword arguments <code class=\"docutils literal notranslate\">virtual_only</code> in <code class=\"docutils literal notranslate\">Field.contribute_to_class()</code> and\n<code class=\"docutils literal notranslate\">virtual</code> in <code class=\"docutils literal notranslate\">Model._meta.add_field()</code> are removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">javascript_catalog()</code> and <code class=\"docutils literal notranslate\">json_catalog()</code> views are removed.</p></li>\n<li><p><code class=\"docutils literal notranslate\">django.contrib.gis.utils.precision_wkt()</code> is removed.</p></li>\n<li><p>In multi-table inheritance, implicit promotion of a <code class=\"docutils literal notranslate\">OneToOneField</code> to a\n<code class=\"docutils literal notranslate\">parent_link</code> is removed.</p></li>\n<li><p>Support for <code class=\"docutils literal notranslate\">Widget._format_value()</code> is removed.</p></li>\n<li><p><code class=\"docutils literal notranslate\">FileField</code> methods <code class=\"docutils literal notranslate\">get_directory_name()</code> and <code class=\"docutils literal notranslate\">get_filename()</code> are\nremoved.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">mark_for_escaping()</code> function and the classes it uses: <code class=\"docutils literal notranslate\">EscapeData</code>,\n<code class=\"docutils literal notranslate\">EscapeBytes</code>, <code class=\"docutils literal notranslate\">EscapeText</code>, <code class=\"docutils literal notranslate\">EscapeString</code>, and <code class=\"docutils literal notranslate\">EscapeUnicode</code> are\nremoved.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">escape</code> filter now uses <code class=\"docutils literal notranslate\">django.utils.html.conditional_escape()</code>.</p></li>\n<li><p><code class=\"docutils literal notranslate\">Manager.use_for_related_fields</code> is removed.</p></li>\n<li><p>Model <code class=\"docutils literal notranslate\">Manager</code> inheritance follows MRO inheritance rules. The requirement\nto use <code class=\"docutils literal notranslate\">Meta.manager_inheritance_from_future</code> to opt-in to the behavior is\nremoved.</p></li>\n<li><p>Support for old-style middleware using <code class=\"docutils literal notranslate\">settings.MIDDLEWARE_CLASSES</code> is\nremoved.</p></li>\n</ul>\n</section>","rootId":"django-2-0-release-notes","toc":[{"title":"Python compatibility","anchor":"python-compatibility","children":[]},{"title":"Third-party library support for older version of Django","anchor":"third-party-library-support-for-older-version-of-django","children":[]},{"title":"What’s new in Django 2.0","anchor":"what-s-new-in-django-2-0","children":[{"title":"Simplified URL routing syntax","anchor":"simplified-url-routing-syntax","children":[]},{"title":"Mobile-friendly contrib.admin","anchor":"mobile-friendly-contrib-admin","children":[]},{"title":"Window expressions","anchor":"window-expressions","children":[]},{"title":"Minor features","anchor":"minor-features","children":[{"title":"django.contrib.admin","anchor":"django-contrib-admin","children":[]},{"title":"django.contrib.auth","anchor":"django-contrib-auth","children":[]},{"title":"django.contrib.gis","anchor":"django-contrib-gis","children":[]},{"title":"django.contrib.postgres","anchor":"django-contrib-postgres","children":[]},{"title":"django.contrib.sitemaps","anchor":"django-contrib-sitemaps","children":[]},{"title":"Cache","anchor":"cache","children":[]},{"title":"File Storage","anchor":"file-storage","children":[]},{"title":"Forms","anchor":"forms","children":[]},{"title":"Generic Views","anchor":"generic-views","children":[]},{"title":"Management Commands","anchor":"management-commands","children":[]},{"title":"Migrations","anchor":"migrations","children":[]},{"title":"Models","anchor":"models","children":[]},{"title":"Pagination","anchor":"pagination","children":[]},{"title":"Requests and Responses","anchor":"requests-and-responses","children":[]},{"title":"Templates","anchor":"templates","children":[]},{"title":"Tests","anchor":"tests","children":[]},{"title":"Validators","anchor":"validators","children":[]}]}]},{"title":"Backwards incompatible changes in 2.0","anchor":"backwards-incompatible-changes-in-2-0","children":[{"title":"Removed support for bytestrings in some places","anchor":"removed-support-for-bytestrings-in-some-places","children":[]},{"title":"Database backend API","anchor":"database-backend-api","children":[]},{"title":"Dropped support for Oracle 11.2","anchor":"dropped-support-for-oracle-11-2","children":[]},{"title":"Default MySQL isolation level is read committed","anchor":"default-mysql-isolation-level-is-read-committed","children":[]},{"title":"AbstractUser.last_name max_length increased to 150","anchor":"abstractuser-last-name-max-length-increased-to-150","children":[]},{"title":"QuerySet.reverse() and last() are prohibited after slicing","anchor":"queryset-reverse-and-last-are-prohibited-after-slicing","children":[]},{"title":"Form fields no longer accept optional arguments as positional arguments","anchor":"form-fields-no-longer-accept-optional-arguments-as-positional-arguments","children":[]},{"title":"call_command() validates the options it receives","anchor":"call-command-validates-the-options-it-receives","children":[]},{"title":"Indexes no longer accept positional arguments","anchor":"indexes-no-longer-accept-positional-arguments","children":[]},{"title":"Foreign key constraints are now enabled on SQLite","anchor":"foreign-key-constraints-are-now-enabled-on-sqlite","children":[]},{"title":"Miscellaneous","anchor":"miscellaneous","children":[]}]},{"title":"Features deprecated in 2.0","anchor":"features-deprecated-in-2-0","children":[{"title":"context argument of Field.from_db_value() and Expression.convert_value()","anchor":"context-argument-of-field-from-db-value-and-expression-convert-value","children":[]},{"title":"Miscellaneous","anchor":"id1","children":[]}]},{"title":"Features removed in 2.0","anchor":"features-removed-in-2-0","children":[]}],"breadcrumbs":[{"docname":"releases/index","title":"Release notes","url":"/en/dev/releases/"}],"prev":{"docname":"releases/2.0.1","title":"Django 2.0.1 release notes","url":"/en/dev/releases/2.0.1/"},"next":{"docname":"releases/1.11.29","title":"Django 1.11.29 release notes","url":"/en/dev/releases/1.11.29/"},"formats":{"html":"/en/dev/releases/2.0/","markdown":"/en/dev/releases/2.0.md","json":"/en/dev/releases/2.0.json"},"source":"https://github.com/django/django/blob/main/docs/releases/2.0.txt","official":"https://docs.djangoproject.com/en/dev/releases/2.0/","inVersions":["dev","6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0"],"inLocales":["en"]}