{"title":"Django 2.1 release notes","version":"dev","locale":"en","docname":"releases/2.1","url":"/en/dev/releases/2.1/","canonical":"https://djangodocs.dev/en/dev/releases/2.1/","summary":"Welcome to Django 2.1! 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.1 release notes<a class=\"heading-anchor\" href=\"#django-2-1-release-notes\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p><em>August 1, 2018</em></p>\n<p>Welcome to Django 2.1!</p>\n<p>These release notes cover the <a class=\"reference internal\" href=\"#whats-new-2-1\"><span class=\"std std-ref\">new features</span></a>, as well as\nsome <a class=\"reference internal\" href=\"#backwards-incompatible-2-1\"><span class=\"std std-ref\">backwards incompatible changes</span></a> you’ll\nwant to be aware of when upgrading from Django 2.0 or earlier. We’ve\n<a class=\"reference internal\" href=\"#removed-features-2-1\"><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-1\"><span class=\"std std-ref\">begun the deprecation process for some\nfeatures</span></a>.</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.1 supports Python 3.5, 3.6, and 3.7. Django 2.0 is the last version to\nsupport Python 3.4. We <strong>highly recommend</strong> and only officially support the\nlatest release of each series.</p>\n</section>\n<section id=\"what-s-new-in-django-2-1\">\n<span id=\"whats-new-2-1\"></span><h2>What’s new in Django 2.1<a class=\"heading-anchor\" href=\"#what-s-new-in-django-2-1\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"model-view-permission\">\n<h3>Model “view” permission<a class=\"heading-anchor\" href=\"#model-view-permission\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>A “view” permission is added to the model <a class=\"reference internal\" href=\"/en/dev/ref/models/options/#django.db.models.Options.default_permissions\" title=\"django.db.models.Options.default_permissions\"><code class=\"xref py py-attr docutils literal notranslate\">Meta.default_permissions</code></a>. The new permissions will be\ncreated automatically when running <a class=\"reference internal\" href=\"/en/dev/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\">migrate</code></a>.</p>\n<p>This allows giving users read-only access to models in the admin.\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.has_view_permission\" title=\"django.contrib.admin.ModelAdmin.has_view_permission\"><code class=\"xref py py-meth docutils literal notranslate\">ModelAdmin.has_view_permission()</code></a> is new. The implementation is backwards\ncompatible in that there isn’t a need to assign the “view” permission to allow\nusers who have the “change” permission to edit objects.</p>\n<p>There are a couple of <a class=\"reference internal\" href=\"#view-permission-backwards-incompatible\"><span class=\"std std-ref\">backwards incompatible considerations</span></a>.</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><a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.search_fields\" title=\"django.contrib.admin.ModelAdmin.search_fields\"><code class=\"xref py py-attr docutils literal notranslate\">ModelAdmin.search_fields</code></a> now accepts any lookup such as\n<code class=\"docutils literal notranslate\">field__exact</code>.</p></li>\n<li><p>jQuery is upgraded from version 2.2.3 to 3.3.1.</p></li>\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.delete_queryset\" title=\"django.contrib.admin.ModelAdmin.delete_queryset\"><code class=\"xref py py-meth docutils literal notranslate\">ModelAdmin.delete_queryset()</code></a> method allows customizing the\ndeletion process of the “delete selected objects” action.</p></li>\n<li><p>You can now <a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#overriding-default-admin-site\"><span class=\"std std-ref\">override the default admin site</span></a>.</p></li>\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.sortable_by\" title=\"django.contrib.admin.ModelAdmin.sortable_by\"><code class=\"xref py py-attr docutils literal notranslate\">ModelAdmin.sortable_by</code></a> attribute and\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_sortable_by\" title=\"django.contrib.admin.ModelAdmin.get_sortable_by\"><code class=\"xref py py-meth docutils literal notranslate\">ModelAdmin.get_sortable_by()</code></a> method allow limiting the columns that\ncan be sorted in the change list page.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">admin_order_field</code> attribute for elements in\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_display\" title=\"django.contrib.admin.ModelAdmin.list_display\"><code class=\"xref py py-attr docutils literal notranslate\">ModelAdmin.list_display</code></a> may now be a query expression.</p></li>\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_deleted_objects\" title=\"django.contrib.admin.ModelAdmin.get_deleted_objects\"><code class=\"xref py py-meth docutils literal notranslate\">ModelAdmin.get_deleted_objects()</code></a> method allows customizing\nthe deletion process of the delete view and the “delete selected” action.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">actions.html</code>, <code class=\"docutils literal notranslate\">change_list_results.html</code>, <code class=\"docutils literal notranslate\">date_hierarchy.html</code>,\n<code class=\"docutils literal notranslate\">pagination.html</code>, <code class=\"docutils literal notranslate\">prepopulated_fields_js.html</code>, <code class=\"docutils literal notranslate\">search_form.html</code>,\nand <code class=\"docutils literal notranslate\">submit_line.html</code> templates can now be <a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#admin-templates-overridden-per-app-or-model\"><span class=\"std std-ref\">overridden per app or\nper model</span></a> (besides overridden\nglobally).</p></li>\n<li><p>The admin change list and change form object tools can now be\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#admin-templates-overridden-per-app-or-model\"><span class=\"std std-ref\">overridden per app, per model, or globally</span></a> with\n<code class=\"docutils literal notranslate\">change_list_object_tools.html</code> and <code class=\"docutils literal notranslate\">change_form_object_tools.html</code>\ntemplates.</p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#django.contrib.admin.InlineModelAdmin.has_add_permission\" title=\"django.contrib.admin.InlineModelAdmin.has_add_permission\"><code class=\"xref py py-meth docutils literal notranslate\">InlineModelAdmin.has_add_permission()</code></a> is now passed the parent object\nas the second positional argument, <code class=\"docutils literal notranslate\">obj</code>.</p></li>\n<li><p>Admin actions may now <a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/actions/#admin-action-permissions\"><span class=\"std std-ref\">specify permissions</span></a>\nto limit their availability to certain users.</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><a class=\"reference internal\" href=\"/en/dev/ref/django-admin/#django-admin-createsuperuser\"><code class=\"xref std std-djadmin docutils literal notranslate\">createsuperuser</code></a> now gives a prompt to allow bypassing the\n<a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-AUTH_PASSWORD_VALIDATORS\"><code class=\"xref std std-setting docutils literal notranslate\">AUTH_PASSWORD_VALIDATORS</code></a> checks.</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>The new <a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/geos/#django.contrib.gis.geos.GEOSGeometry.buffer_with_style\" title=\"django.contrib.gis.geos.GEOSGeometry.buffer_with_style\"><code class=\"xref py py-meth docutils literal notranslate\">GEOSGeometry.buffer_with_style()</code></a> method is a version of\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/geos/#django.contrib.gis.geos.GEOSGeometry.buffer\" title=\"django.contrib.gis.geos.GEOSGeometry.buffer\"><code class=\"xref py py-meth docutils literal notranslate\">buffer()</code></a> that allows customizing the style of the\nbuffer.</p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/forms-api/#django.contrib.gis.forms.widgets.OpenLayersWidget\" title=\"django.contrib.gis.forms.widgets.OpenLayersWidget\"><code class=\"xref py py-class docutils literal notranslate\">OpenLayersWidget</code></a> is now based on\nOpenLayers 4.6.5 (previously 3.20.1).</p></li>\n</ul>\n</section>\n<section id=\"django-contrib-sessions\">\n<h4><a class=\"reference internal\" href=\"/en/dev/topics/http/sessions/#module-django.contrib.sessions\" title=\"django.contrib.sessions: Provides session management for Django projects.\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.sessions</code></a><a class=\"heading-anchor\" href=\"#django-contrib-sessions\"><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 <a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-SESSION_COOKIE_SAMESITE\"><code class=\"xref std std-setting docutils literal notranslate\">SESSION_COOKIE_SAMESITE</code></a> setting to set the <code class=\"docutils literal notranslate\">SameSite</code>\ncookie flag on session cookies.</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>The <a class=\"reference internal\" href=\"/en/dev/topics/cache/#local-memory-caching\"><span class=\"std std-ref\">local-memory cache backend</span></a> now uses a\nleast-recently-used (LRU) culling strategy rather than a pseudo-random one.</p></li>\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/topics/cache/#django.core.cache.cache.touch\" title=\"django.core.cache.cache.touch\"><code class=\"xref py py-meth docutils literal notranslate\">touch()</code></a> method of the <a class=\"reference internal\" href=\"/en/dev/topics/cache/#low-level-cache-api\"><span class=\"std std-ref\">low-level\ncache API</span></a> updates the timeout of cache keys.</p></li>\n</ul>\n</section>\n<section id=\"csrf\">\n<h4>CSRF<a class=\"heading-anchor\" href=\"#csrf\"><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 <a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-CSRF_COOKIE_SAMESITE\"><code class=\"xref std std-setting docutils literal notranslate\">CSRF_COOKIE_SAMESITE</code></a> setting to set the <code class=\"docutils literal notranslate\">SameSite</code>\ncookie flag on CSRF cookies.</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 widget for <code class=\"docutils literal notranslate\">ImageField</code> now renders with the HTML attribute\n<code class=\"docutils literal notranslate\">accept=&quot;image/*&quot;</code>.</p></li>\n</ul>\n</section>\n<section id=\"internationalization\">\n<h4>Internationalization<a class=\"heading-anchor\" href=\"#internationalization\"><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 <a class=\"reference internal\" href=\"/en/dev/ref/utils/#django.utils.translation.get_supported_language_variant\" title=\"django.utils.translation.get_supported_language_variant\"><code class=\"xref py py-meth docutils literal notranslate\">get_supported_language_variant()</code></a>\nfunction.</p></li>\n<li><p>Untranslated strings for territorial language variants now use the\ntranslations of the generic language. For example, untranslated <code class=\"docutils literal notranslate\">pt_BR</code>\nstrings use <code class=\"docutils literal notranslate\">pt</code> translations.</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>The new <a class=\"reference internal\" href=\"/en/dev/ref/django-admin/#cmdoption-inspectdb-include-views\"><code class=\"xref std std-option docutils literal notranslate\">inspectdb --include-views</code></a> option allows creating models\nfor database views.</p></li>\n<li><p>The <a class=\"reference internal\" href=\"/en/dev/howto/custom-management-commands/#django.core.management.BaseCommand\" title=\"django.core.management.BaseCommand\"><code class=\"xref py py-class docutils literal notranslate\">BaseCommand</code></a> class now uses a custom help\nformatter so that the standard options like <code class=\"docutils literal notranslate\">--verbosity</code> or <code class=\"docutils literal notranslate\">--settings</code>\nappear last in the help output, giving a more prominent position to\nsubclassed command’s options.</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>Added support for serialization of <code class=\"docutils literal notranslate\">functools.partialmethod</code> objects.</p></li>\n<li><p>To support frozen environments, migrations may be loaded from <code class=\"docutils literal notranslate\">.pyc</code> files.</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>Models can now use <code class=\"docutils literal notranslate\">__init_subclass__()</code> from <span class=\"target\" id=\"index-0\"></span><a class=\"pep reference external\" href=\"https://peps.python.org/pep-0487/\"><strong>PEP 487</strong></a>.</p></li>\n<li><p>A <code class=\"docutils literal notranslate\">BinaryField</code> may now be set to <code class=\"docutils literal notranslate\">editable=True</code> if you wish to include\nit in model forms.</p></li>\n<li><p>A number of new text database functions are added:\n<a class=\"reference internal\" href=\"/en/dev/ref/models/database-functions/#django.db.models.functions.Chr\" title=\"django.db.models.functions.Chr\"><code class=\"xref py py-class docutils literal notranslate\">Chr</code></a>,\n<a class=\"reference internal\" href=\"/en/dev/ref/models/database-functions/#django.db.models.functions.Left\" title=\"django.db.models.functions.Left\"><code class=\"xref py py-class docutils literal notranslate\">Left</code></a>,\n<a class=\"reference internal\" href=\"/en/dev/ref/models/database-functions/#django.db.models.functions.LPad\" title=\"django.db.models.functions.LPad\"><code class=\"xref py py-class docutils literal notranslate\">LPad</code></a>,\n<a class=\"reference internal\" href=\"/en/dev/ref/models/database-functions/#django.db.models.functions.LTrim\" title=\"django.db.models.functions.LTrim\"><code class=\"xref py py-class docutils literal notranslate\">LTrim</code></a>,\n<a class=\"reference internal\" href=\"/en/dev/ref/models/database-functions/#django.db.models.functions.Ord\" title=\"django.db.models.functions.Ord\"><code class=\"xref py py-class docutils literal notranslate\">Ord</code></a>,\n<a class=\"reference internal\" href=\"/en/dev/ref/models/database-functions/#django.db.models.functions.Repeat\" title=\"django.db.models.functions.Repeat\"><code class=\"xref py py-class docutils literal notranslate\">Repeat</code></a>,\n<a class=\"reference internal\" href=\"/en/dev/ref/models/database-functions/#django.db.models.functions.Replace\" title=\"django.db.models.functions.Replace\"><code class=\"xref py py-class docutils literal notranslate\">Replace</code></a>,\n<a class=\"reference internal\" href=\"/en/dev/ref/models/database-functions/#django.db.models.functions.Right\" title=\"django.db.models.functions.Right\"><code class=\"xref py py-class docutils literal notranslate\">Right</code></a>,\n<a class=\"reference internal\" href=\"/en/dev/ref/models/database-functions/#django.db.models.functions.RPad\" title=\"django.db.models.functions.RPad\"><code class=\"xref py py-class docutils literal notranslate\">RPad</code></a>,\n<a class=\"reference internal\" href=\"/en/dev/ref/models/database-functions/#django.db.models.functions.RTrim\" title=\"django.db.models.functions.RTrim\"><code class=\"xref py py-class docutils literal notranslate\">RTrim</code></a>, and\n<a class=\"reference internal\" href=\"/en/dev/ref/models/database-functions/#django.db.models.functions.Trim\" title=\"django.db.models.functions.Trim\"><code class=\"xref py py-class docutils literal notranslate\">Trim</code></a>.</p></li>\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/models/database-functions/#django.db.models.functions.TruncWeek\" title=\"django.db.models.functions.TruncWeek\"><code class=\"xref py py-class docutils literal notranslate\">TruncWeek</code></a> function truncates\n<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 Monday of a week.</p></li>\n<li><p>Query expressions can now be negated using a minus sign.</p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.order_by\" title=\"django.db.models.query.QuerySet.order_by\"><code class=\"xref py py-meth docutils literal notranslate\">QuerySet.order_by()</code></a> and <a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.distinct\" title=\"django.db.models.query.QuerySet.distinct\"><code class=\"xref py py-meth docutils literal notranslate\">distinct(*fields)</code></a>\nnow support using field transforms.</p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/models/fields/#django.db.models.BooleanField\" title=\"django.db.models.BooleanField\"><code class=\"xref py py-class docutils literal notranslate\">BooleanField</code></a> can now be <code class=\"docutils literal notranslate\">null=True</code>. This is\nencouraged instead of <code class=\"docutils literal notranslate\">NullBooleanField</code>, which will likely be deprecated\nin the future.</p></li>\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.explain\" title=\"django.db.models.query.QuerySet.explain\"><code class=\"xref py py-meth docutils literal notranslate\">QuerySet.explain()</code></a> method displays the database’s execution\nplan of a queryset’s query.</p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.raw\" title=\"django.db.models.query.QuerySet.raw\"><code class=\"xref py py-meth docutils literal notranslate\">QuerySet.raw()</code></a> now supports <a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.prefetch_related\" title=\"django.db.models.query.QuerySet.prefetch_related\"><code class=\"xref py py-meth docutils literal notranslate\">prefetch_related()</code></a>.</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>Added <a class=\"reference internal\" href=\"/en/dev/ref/request-response/#django.http.HttpRequest.get_full_path_info\" title=\"django.http.HttpRequest.get_full_path_info\"><code class=\"xref py py-meth docutils literal notranslate\">HttpRequest.get_full_path_info()</code></a>.</p></li>\n<li><p>Added the <code class=\"docutils literal notranslate\">samesite</code> argument to <a class=\"reference internal\" href=\"/en/dev/ref/request-response/#django.http.HttpResponse.set_cookie\" title=\"django.http.HttpResponse.set_cookie\"><code class=\"xref py py-meth docutils literal notranslate\">HttpResponse.set_cookie()</code></a> to allow\nsetting the <code class=\"docutils literal notranslate\">SameSite</code> cookie flag.</p></li>\n<li><p>The new <code class=\"docutils literal notranslate\">as_attachment</code> argument for <a class=\"reference internal\" href=\"/en/dev/ref/request-response/#django.http.FileResponse\" title=\"django.http.FileResponse\"><code class=\"xref py py-class docutils literal notranslate\">FileResponse</code></a>\nsets the <code class=\"docutils literal notranslate\">Content-Disposition</code> header to make the browser ask if the user\nwants to download the file. <code class=\"docutils literal notranslate\">FileResponse</code> also tries to set the\n<code class=\"docutils literal notranslate\">Content-Type</code> and <code class=\"docutils literal notranslate\">Content-Length</code> headers where appropriate.</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>The new <a class=\"reference internal\" href=\"/en/dev/ref/templates/builtins/#std-templatefilter-json_script\"><code class=\"xref std std-tfilter docutils literal notranslate\">json_script</code></a> filter safely outputs a Python object as JSON,\nwrapped in a <code class=\"docutils literal notranslate\">&lt;script&gt;</code> tag, ready for use with JavaScript.</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 test <a class=\"reference internal\" href=\"/en/dev/topics/testing/tools/#django.test.Client\" title=\"django.test.Client\"><code class=\"xref py py-class docutils literal notranslate\">Client</code></a> support for 307 and 308 redirects.</p></li>\n<li><p>The test <a class=\"reference internal\" href=\"/en/dev/topics/testing/tools/#django.test.Client\" title=\"django.test.Client\"><code class=\"xref py py-class docutils literal notranslate\">Client</code></a> now serializes a request data\ndictionary as JSON if <code class=\"docutils literal notranslate\">content_type='application/json'</code>. You can customize\nthe JSON encoder with test client’s <code class=\"docutils literal notranslate\">json_encoder</code> parameter.</p></li>\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/topics/testing/tools/#django.test.SimpleTestCase.assertWarnsMessage\" title=\"django.test.SimpleTestCase.assertWarnsMessage\"><code class=\"xref py py-meth docutils literal notranslate\">SimpleTestCase.assertWarnsMessage()</code></a> method is a simpler\nversion of <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertWarnsRegex\" title=\"(in Python v3.14)\"><code class=\"xref py py-meth docutils literal notranslate\">assertWarnsRegex()</code></a>.</p></li>\n</ul>\n</section>\n</section>\n</section>\n<section id=\"backwards-incompatible-changes-in-2-1\">\n<span id=\"backwards-incompatible-2-1\"></span><h2>Backwards incompatible changes in 2.1<a class=\"heading-anchor\" href=\"#backwards-incompatible-changes-in-2-1\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\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>To adhere to <span class=\"target\" id=\"index-1\"></span><a class=\"pep reference external\" href=\"https://peps.python.org/pep-0249/\"><strong>PEP 249</strong></a>, exceptions where a database doesn’t support a\nfeature are changed from <a class=\"reference external\" href=\"https://docs.python.org/3/library/exceptions.html#NotImplementedError\" title=\"(in Python v3.14)\"><code class=\"xref py py-exc docutils literal notranslate\">NotImplementedError</code></a> to\n<a class=\"reference internal\" href=\"/en/dev/ref/exceptions/#django.db.NotSupportedError\" title=\"django.db.NotSupportedError\"><code class=\"xref py py-exc docutils literal notranslate\">django.db.NotSupportedError</code></a>.</p></li>\n<li><p>Renamed the <code class=\"docutils literal notranslate\">allow_sliced_subqueries</code> database feature flag to\n<code class=\"docutils literal notranslate\">allow_sliced_subqueries_with_in</code>.</p></li>\n<li><p><code class=\"docutils literal notranslate\">DatabaseOperations.distinct_sql()</code> now requires an additional <code class=\"docutils literal notranslate\">params</code>\nargument and returns a tuple of SQL and parameters instead of an SQL string.</p></li>\n<li><p><code class=\"docutils literal notranslate\">DatabaseFeatures.introspected_boolean_field_type</code> is changed from a method\nto a property.</p></li>\n</ul>\n</section>\n<section id=\"id1\">\n<h3><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=\"#id1\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<ul class=\"simple\">\n<li><p>Support for SpatiaLite 4.0 is removed.</p></li>\n</ul>\n</section>\n<section id=\"dropped-support-for-mysql-5-5\">\n<h3>Dropped support for MySQL 5.5<a class=\"heading-anchor\" href=\"#dropped-support-for-mysql-5-5\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The end of upstream support for MySQL 5.5 is December 2018. Django 2.1 supports\nMySQL 5.6 and higher.</p>\n</section>\n<section id=\"dropped-support-for-postgresql-9-3\">\n<h3>Dropped support for PostgreSQL 9.3<a class=\"heading-anchor\" href=\"#dropped-support-for-postgresql-9-3\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The end of upstream support for PostgreSQL 9.3 is September 2018. Django 2.1\nsupports PostgreSQL 9.4 and higher.</p>\n</section>\n<section id=\"removed-bcryptpasswordhasher-from-the-default-password-hashers-setting\">\n<h3>Removed <code class=\"docutils literal notranslate\">BCryptPasswordHasher</code> from the default <code class=\"docutils literal notranslate\">PASSWORD_HASHERS</code> setting<a class=\"heading-anchor\" href=\"#removed-bcryptpasswordhasher-from-the-default-password-hashers-setting\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>If you used bcrypt with Django 1.4 or 1.5 (before\n<code class=\"docutils literal notranslate\">BCryptSHA256PasswordHasher</code> was added in Django 1.6), you might have some\npasswords that use the <code class=\"docutils literal notranslate\">BCryptPasswordHasher</code> hasher.</p>\n<p>You can check if that’s the case like 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.contrib.auth</span> <span class=\"kn\">import</span> get_user_model\n\nUser <span class=\"o\">=</span> get_user_model<span class=\"p\">()</span>\nUser<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>password__startswith<span class=\"o\">=</span><span class=\"s2\">&quot;bcrypt$$&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>If you want to continue to allow those passwords to be used, you’ll\nhave to define the <a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-PASSWORD_HASHERS\"><code class=\"xref std std-setting docutils literal notranslate\">PASSWORD_HASHERS</code></a> setting (if you don’t already)\nand include <code class=\"docutils literal notranslate\">'django.contrib.auth.hashers.BCryptPasswordHasher'</code>.</p>\n</section>\n<section id=\"moved-wrap-label-widget-template-context-variable\">\n<h3>Moved <code class=\"docutils literal notranslate\">wrap_label</code> widget template context variable<a class=\"heading-anchor\" href=\"#moved-wrap-label-widget-template-context-variable\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>To fix the lack of <code class=\"docutils literal notranslate\">&lt;label&gt;</code> when using <code class=\"docutils literal notranslate\">RadioSelect</code> and\n<code class=\"docutils literal notranslate\">CheckboxSelectMultiple</code> with <code class=\"docutils literal notranslate\">MultiWidget</code>, the <code class=\"docutils literal notranslate\">wrap_label</code> context\nvariable now appears as an attribute of each option. For example, in a custom\n<code class=\"docutils literal notranslate\">input_option.html</code> template, change <code class=\"docutils literal notranslate\">{% if wrap_label %}</code> to\n<code class=\"docutils literal notranslate\">{% if widget.wrap_label %}</code>.</p>\n</section>\n<section id=\"samesite-cookies\">\n<h3><code class=\"docutils literal notranslate\">SameSite</code> cookies<a class=\"heading-anchor\" href=\"#samesite-cookies\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The cookies used for <code class=\"docutils literal notranslate\">django.contrib.sessions</code>, <code class=\"docutils literal notranslate\">django.contrib.messages</code>,\nand Django’s CSRF protection now set the <code class=\"docutils literal notranslate\">SameSite</code> flag to <code class=\"docutils literal notranslate\">Lax</code> by\ndefault. Browsers that respect this flag won’t send these cookies on\ncross-origin requests. If you rely on the old behavior, set the\n<a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-SESSION_COOKIE_SAMESITE\"><code class=\"xref std std-setting docutils literal notranslate\">SESSION_COOKIE_SAMESITE</code></a> and/or <a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-CSRF_COOKIE_SAMESITE\"><code class=\"xref std std-setting docutils literal notranslate\">CSRF_COOKIE_SAMESITE</code></a>\nsetting to <code class=\"docutils literal notranslate\">None</code>.</p>\n</section>\n<section id=\"considerations-for-the-new-model-view-permission\">\n<span id=\"view-permission-backwards-incompatible\"></span><h3>Considerations for the new model “view” permission<a class=\"heading-anchor\" href=\"#considerations-for-the-new-model-view-permission\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<section id=\"custom-admin-forms-need-to-take-the-view-only-case-into-account\">\n<h4>Custom admin forms need to take the view-only case into account<a class=\"heading-anchor\" href=\"#custom-admin-forms-need-to-take-the-view-only-case-into-account\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>With the new “view” permission, existing custom admin forms may raise errors\nwhen a user doesn’t have the change permission because the form might access\nnonexistent fields. Fix this by overriding <a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_form\" title=\"django.contrib.admin.ModelAdmin.get_form\"><code class=\"xref py py-meth docutils literal notranslate\">ModelAdmin.get_form()</code></a> and\nchecking if the user has the “change” permissions and returning the default\nform if not:</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\">MyAdmin</span><span class=\"p\">(</span>admin<span class=\"o\">.</span>ModelAdmin<span class=\"p\">):</span>\n    <span class=\"k\">def</span> <span class=\"nf\">get_form</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> request<span class=\"p\">,</span> obj<span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"bp\">self</span><span class=\"o\">.</span>has_change_permission<span class=\"p\">(</span>request<span class=\"p\">,</span> obj<span class=\"p\">):</span>\n            <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span>get_form<span class=\"p\">(</span>request<span class=\"p\">,</span> obj<span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<span class=\"p\">)</span>\n        <span class=\"k\">return</span> CustomForm\n</code></pre></div>\n</section>\n<section id=\"new-default-view-permission-could-allow-unwanted-access-to-admin-views\">\n<h4>New default view permission could allow unwanted access to admin views<a class=\"heading-anchor\" href=\"#new-default-view-permission-could-allow-unwanted-access-to-admin-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>If you have a custom permission with a codename of the form\n<code class=\"docutils literal notranslate\">view_&lt;modelname&gt;</code>, the new view permission handling in the admin will allow\nview access to the changelist and detail pages for those models. If this is\nunwanted, you must change your custom permission codename.</p>\n</section>\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 class=\"simple\">\n<li><p>The minimum supported version of <code class=\"docutils literal notranslate\">mysqlclient</code> is increased from 1.3.3 to\n1.3.7.</p></li>\n<li><p>Support for SQLite &lt; 3.7.15 is removed.</p></li>\n<li><p>The date format of <code class=\"docutils literal notranslate\">Set-Cookie</code>’s <code class=\"docutils literal notranslate\">Expires</code> directive is changed to\nfollow <span class=\"target\" id=\"index-2\"></span><a class=\"rfc reference external\" href=\"https://datatracker.ietf.org/doc/html/rfc7231.html#section-7.1.1.1\"><strong>RFC 7231 Section 7.1.1.1</strong></a> instead of Netscape’s cookie standard.\nHyphens present in dates like <code class=\"docutils literal notranslate\">Tue, 25-Dec-2018 22:26:13 GMT</code> are removed.\nThis change should be merely cosmetic except perhaps for antiquated browsers\nthat don’t parse the new format.</p></li>\n<li><p><code class=\"docutils literal notranslate\">allowed_hosts</code> is now a required argument of private API\n<code class=\"docutils literal notranslate\">django.utils.http.is_safe_url()</code>.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">multiple</code> attribute rendered by the\n<a class=\"reference internal\" href=\"/en/dev/ref/forms/widgets/#django.forms.SelectMultiple\" title=\"django.forms.SelectMultiple\"><code class=\"xref py py-class docutils literal notranslate\">SelectMultiple</code></a> widget now uses HTML5 boolean syntax\nrather than XHTML’s <code class=\"docutils literal notranslate\">multiple=&quot;multiple&quot;</code>.</p></li>\n<li><p>HTML rendered by form widgets no longer includes a closing slash on void\nelements, e.g. <code class=\"docutils literal notranslate\">&lt;br&gt;</code>. This is incompatible within XHTML, although some\nwidgets already used aspects of HTML5 such as boolean attributes.</p></li>\n<li><p>The value of <a class=\"reference internal\" href=\"/en/dev/ref/forms/widgets/#django.forms.SelectDateWidget\" title=\"django.forms.SelectDateWidget\"><code class=\"xref py py-class docutils literal notranslate\">SelectDateWidget</code></a>’s empty options is\nchanged from 0 to an empty string, which mainly may require some adjustments\nin tests that compare HTML.</p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/contrib/auth/#django.contrib.auth.models.User.has_usable_password\" title=\"django.contrib.auth.models.User.has_usable_password\"><code class=\"xref py py-meth docutils literal notranslate\">User.has_usable_password()</code></a> and the\n<a class=\"reference internal\" href=\"/en/dev/topics/auth/passwords/#django.contrib.auth.hashers.is_password_usable\" title=\"django.contrib.auth.hashers.is_password_usable\"><code class=\"xref py py-func docutils literal notranslate\">is_password_usable()</code></a> function no longer\nreturn <code class=\"docutils literal notranslate\">False</code> if the password is <code class=\"docutils literal notranslate\">None</code> or an empty string, or if the\npassword uses a hasher that’s not in the <a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-PASSWORD_HASHERS\"><code class=\"xref std std-setting docutils literal notranslate\">PASSWORD_HASHERS</code></a> setting.\nThis undocumented behavior was a regression in Django 1.6 and prevented users\nwith such passwords from requesting a password reset. Audit your code to\nconfirm that your usage of these APIs don’t rely on the old behavior.</p></li>\n<li><p>Since migrations are now loaded from <code class=\"docutils literal notranslate\">.pyc</code> files, you might need to delete\nthem if you’re working in a mixed Python 2 and Python 3 environment.</p></li>\n<li><p>Using <code class=\"docutils literal notranslate\">None</code> as a <code class=\"docutils literal notranslate\">django.contrib.postgres.fields.JSONField</code> lookup\nvalue now matches objects that have the specified key and a null value rather\nthan objects that don’t have the key.</p></li>\n<li><p>The admin CSS class <code class=\"docutils literal notranslate\">field-box</code> is renamed to <code class=\"docutils literal notranslate\">fieldBox</code> to prevent\nconflicts with the class given to model fields named “box”.</p></li>\n<li><p>Since the admin’s <code class=\"docutils literal notranslate\">actions.html</code>, <code class=\"docutils literal notranslate\">change_list_results.html</code>,\n<code class=\"docutils literal notranslate\">date_hierarchy.html</code>, <code class=\"docutils literal notranslate\">pagination.html</code>,\n<code class=\"docutils literal notranslate\">prepopulated_fields_js.html</code>, <code class=\"docutils literal notranslate\">search_form.html</code>, and\n<code class=\"docutils literal notranslate\">submit_line.html</code> templates can now be overridden per app or per model,\nyou may need to rename existing templates with those names that were written\nfor a different purpose.</p></li>\n<li><p><code class=\"docutils literal notranslate\">QuerySet.raw()</code> now caches its results like regular querysets. Use\n<code class=\"docutils literal notranslate\">iterator()</code> if you don’t want caching.</p></li>\n<li><p>The database router <a class=\"reference internal\" href=\"/en/dev/topics/db/multi-db/#allow_relation\" title=\"allow_relation\"><code class=\"xref py py-meth docutils literal notranslate\">allow_relation()</code></a> method is called in more cases.\nImproperly written routers may need to be updated accordingly.</p></li>\n<li><p>Translations are no longer deactivated before running management commands.\nIf your custom command requires translations to be deactivated (for example,\nto insert untranslated content into the database), use the new\n<a class=\"reference internal\" href=\"/en/dev/howto/custom-management-commands/#management-commands-and-locales\"><span class=\"std std-ref\">&#64;no_translations decorator</span></a>.</p></li>\n<li><p>Management commands no longer allow the abbreviated forms of the\n<code class=\"docutils literal notranslate\">--settings</code> and <code class=\"docutils literal notranslate\">--pythonpath</code> arguments.</p></li>\n<li><p>The private <code class=\"docutils literal notranslate\">django.db.models.sql.constants.QUERY_TERMS</code> constant is\nremoved. The <a class=\"reference internal\" href=\"/en/dev/ref/models/lookups/#django.db.models.lookups.RegisterLookupMixin.get_lookup\" title=\"django.db.models.lookups.RegisterLookupMixin.get_lookup\"><code class=\"xref py py-meth docutils literal notranslate\">get_lookup()</code></a>\nand <a class=\"reference internal\" href=\"/en/dev/ref/models/lookups/#django.db.models.lookups.RegisterLookupMixin.get_lookups\" title=\"django.db.models.lookups.RegisterLookupMixin.get_lookups\"><code class=\"xref py py-meth docutils literal notranslate\">get_lookups()</code></a> methods\nof the <a class=\"reference internal\" href=\"/en/dev/ref/models/lookups/#lookup-registration-api\"><span class=\"std std-ref\">Lookup Registration API</span></a> may be\nsuitable alternatives. Compared to the <code class=\"docutils literal notranslate\">QUERY_TERMS</code> constant, they allow\nyour code to also account for any custom lookups that have been registered.</p></li>\n<li><p>Compatibility with <code class=\"docutils literal notranslate\">py-bcrypt</code> is removed as it’s unmaintained. Use\n<a class=\"extlink-pypi reference external\" href=\"https://pypi.org/project/bcrypt/\">bcrypt</a> instead.</p></li>\n</ul>\n</section>\n</section>\n<section id=\"features-deprecated-in-2-1\">\n<span id=\"deprecated-features-2-1\"></span><h2>Features deprecated in 2.1<a class=\"heading-anchor\" href=\"#features-deprecated-in-2-1\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"id2\">\n<h3>Miscellaneous<a class=\"heading-anchor\" href=\"#id2\"><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\">ForceRHR</code> GIS function is deprecated in favor of the new\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.ForcePolygonCW\" title=\"django.contrib.gis.db.models.functions.ForcePolygonCW\"><code class=\"xref py py-class docutils literal notranslate\">ForcePolygonCW</code></a> function.</p></li>\n<li><p><code class=\"docutils literal notranslate\">django.utils.http.cookie_date()</code> is deprecated in favor of\n<a class=\"reference internal\" href=\"/en/dev/ref/utils/#django.utils.http.http_date\" title=\"django.utils.http.http_date\"><code class=\"xref py py-func docutils literal notranslate\">http_date()</code></a>, which follows the format of the latest\nRFC.</p></li>\n<li><p><code class=\"docutils literal notranslate\">{% load staticfiles %}</code> and <code class=\"docutils literal notranslate\">{% load admin_static %}</code> are deprecated\nin favor of <code class=\"docutils literal notranslate\">{% load static %}</code>, which works the same.</p></li>\n<li><p><code class=\"docutils literal notranslate\">django.contrib.staticfiles.templatetags.static()</code> is deprecated in favor\nof <code class=\"docutils literal notranslate\">django.templatetags.static.static()</code>.</p></li>\n<li><p>Support for <a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#django.contrib.admin.InlineModelAdmin.has_add_permission\" title=\"django.contrib.admin.InlineModelAdmin.has_add_permission\"><code class=\"xref py py-meth docutils literal notranslate\">InlineModelAdmin.has_add_permission()</code></a> methods that don’t\naccept <code class=\"docutils literal notranslate\">obj</code> as the second positional argument will be removed in Django\n3.0.</p></li>\n</ul>\n</section>\n</section>\n<section id=\"features-removed-in-2-1\">\n<span id=\"removed-features-2-1\"></span><h2>Features removed in 2.1<a class=\"heading-anchor\" href=\"#features-removed-in-2-1\"><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.1. See <a class=\"reference internal\" href=\"/en/dev/releases/1.11/#deprecated-features-1-11\"><span class=\"std std-ref\">Features deprecated in 1.11</span></a> for details, including how\nto remove usage of these features.</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\">contrib.auth.views.login()</code>, <code class=\"docutils literal notranslate\">logout()</code>, <code class=\"docutils literal notranslate\">password_change()</code>,\n<code class=\"docutils literal notranslate\">password_change_done()</code>, <code class=\"docutils literal notranslate\">password_reset()</code>, <code class=\"docutils literal notranslate\">password_reset_done()</code>,\n<code class=\"docutils literal notranslate\">password_reset_confirm()</code>, and <code class=\"docutils literal notranslate\">password_reset_complete()</code> are removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">extra_context</code> parameter of <code class=\"docutils literal notranslate\">contrib.auth.views.logout_then_login()</code>\nis removed.</p></li>\n<li><p><code class=\"docutils literal notranslate\">django.test.runner.setup_databases()</code> is removed.</p></li>\n<li><p><code class=\"docutils literal notranslate\">django.utils.translation.string_concat()</code> is removed.</p></li>\n<li><p><code class=\"docutils literal notranslate\">django.core.cache.backends.memcached.PyLibMCCache</code> no longer supports\npassing <code class=\"docutils literal notranslate\">pylibmc</code> behavior settings as top-level attributes of <code class=\"docutils literal notranslate\">OPTIONS</code>.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">host</code> parameter of <code class=\"docutils literal notranslate\">django.utils.http.is_safe_url()</code> is removed.</p></li>\n<li><p>Silencing of exceptions raised while rendering the <code class=\"docutils literal notranslate\">{% include %}</code> template\ntag is removed.</p></li>\n<li><p><code class=\"docutils literal notranslate\">DatabaseIntrospection.get_indexes()</code> is removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">authenticate()</code> method of authentication backends requires <code class=\"docutils literal notranslate\">request</code>\nas the first positional argument.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">django.db.models.permalink()</code> decorator is removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">USE_ETAGS</code> setting is removed. <code class=\"docutils literal notranslate\">CommonMiddleware</code> and\n<code class=\"docutils literal notranslate\">django.utils.cache.patch_response_headers()</code> no longer set ETags.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">Model._meta.has_auto_field</code> attribute is removed.</p></li>\n<li><p><code class=\"docutils literal notranslate\">url()</code>’s support for inline flags in regular expression groups (<code class=\"docutils literal notranslate\">(?i)</code>,\n<code class=\"docutils literal notranslate\">(?L)</code>, <code class=\"docutils literal notranslate\">(?m)</code>, <code class=\"docutils literal notranslate\">(?s)</code>, and <code class=\"docutils literal notranslate\">(?u)</code>) is removed.</p></li>\n<li><p>Support for <code class=\"docutils literal notranslate\">Widget.render()</code> methods without the <code class=\"docutils literal notranslate\">renderer</code> argument\nis removed.</p></li>\n</ul>\n</section>","rootId":"django-2-1-release-notes","toc":[{"title":"Python compatibility","anchor":"python-compatibility","children":[]},{"title":"What’s new in Django 2.1","anchor":"what-s-new-in-django-2-1","children":[{"title":"Model “view” permission","anchor":"model-view-permission","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.sessions","anchor":"django-contrib-sessions","children":[]},{"title":"Cache","anchor":"cache","children":[]},{"title":"CSRF","anchor":"csrf","children":[]},{"title":"Forms","anchor":"forms","children":[]},{"title":"Internationalization","anchor":"internationalization","children":[]},{"title":"Management Commands","anchor":"management-commands","children":[]},{"title":"Migrations","anchor":"migrations","children":[]},{"title":"Models","anchor":"models","children":[]},{"title":"Requests and Responses","anchor":"requests-and-responses","children":[]},{"title":"Templates","anchor":"templates","children":[]},{"title":"Tests","anchor":"tests","children":[]}]}]},{"title":"Backwards incompatible changes in 2.1","anchor":"backwards-incompatible-changes-in-2-1","children":[{"title":"Database backend API","anchor":"database-backend-api","children":[]},{"title":"django.contrib.gis","anchor":"id1","children":[]},{"title":"Dropped support for MySQL 5.5","anchor":"dropped-support-for-mysql-5-5","children":[]},{"title":"Dropped support for PostgreSQL 9.3","anchor":"dropped-support-for-postgresql-9-3","children":[]},{"title":"Removed BCryptPasswordHasher from the default PASSWORD_HASHERS setting","anchor":"removed-bcryptpasswordhasher-from-the-default-password-hashers-setting","children":[]},{"title":"Moved wrap_label widget template context variable","anchor":"moved-wrap-label-widget-template-context-variable","children":[]},{"title":"SameSite cookies","anchor":"samesite-cookies","children":[]},{"title":"Considerations for the new model “view” permission","anchor":"considerations-for-the-new-model-view-permission","children":[{"title":"Custom admin forms need to take the view-only case into account","anchor":"custom-admin-forms-need-to-take-the-view-only-case-into-account","children":[]},{"title":"New default view permission could allow unwanted access to admin views","anchor":"new-default-view-permission-could-allow-unwanted-access-to-admin-views","children":[]}]},{"title":"Miscellaneous","anchor":"miscellaneous","children":[]}]},{"title":"Features deprecated in 2.1","anchor":"features-deprecated-in-2-1","children":[{"title":"Miscellaneous","anchor":"id2","children":[]}]},{"title":"Features removed in 2.1","anchor":"features-removed-in-2-1","children":[]}],"breadcrumbs":[{"docname":"releases/index","title":"Release notes","url":"/en/dev/releases/"}],"prev":{"docname":"releases/2.1.1","title":"Django 2.1.1 release notes","url":"/en/dev/releases/2.1.1/"},"next":{"docname":"releases/2.0.13","title":"Django 2.0.13 release notes","url":"/en/dev/releases/2.0.13/"},"formats":{"html":"/en/dev/releases/2.1/","markdown":"/en/dev/releases/2.1.md","json":"/en/dev/releases/2.1.json"},"source":"https://github.com/django/django/blob/main/docs/releases/2.1.txt","official":"https://docs.djangoproject.com/en/dev/releases/2.1/","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"],"inLocales":["en"]}