NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #537 most downloaded on PyPI
A high-level Python web framework that encourages rapid development and clean, pragmatic design.
Last release 26 days ago
02 Sep 2026
Ships fairly regularly
a new release about every 3 weeks
Nearly every release is documented
notes for 54 of the last 60 stable releases
2 versions withdrawn
withdrawn after publishing
16 years old
442 releases · first in 2010
Django 2.1.12 fixes a regression in 2.1.11.
September 2, 2019
Django 2.1.12 fixes a regression in 2.1.11.
Fixed crash of KeyTransform() for django.contrib.postgres.fields.JSONField and ~django.contrib.postgres.fields.HStoreField when using on expressions with params (30672).
CVE-2019-14232: Denial-of-service possibility in django.utils.text.Truncator
August 1, 2019
Django 2.1.11 fixes security issues in 2.1.10.
If django.utils.text.Truncator's chars() and words() methods were passed the html=True argument, they were extremely slow to evaluate certain inputs due to a catastrophic backtracking vulnerability in a regular expression. The chars() and words() methods are used to implement the truncatechars_html and truncatewords_html template filters, which were thus vulnerable.
The regular expressions used by Truncator have been simplified in order to avoid potential backtracking issues. As a consequence, trailing punctuation may now at times be included in the truncated output.
Due to the behavior of the underlying HTMLParser, django.utils.html.strip_tags would be extremely slow to evaluate certain inputs containing large sequences of nested incomplete HTML entities. The strip_tags() method is used to implement the corresponding striptags template filter, which was thus also vulnerable.
strip_tags() now avoids recursive calls to HTMLParser when progress removing tags, but necessarily incomplete HTML entities, stops being made.
Remember that absolutely NO guarantee is provided about the results of strip_tags() being HTML safe. So NEVER mark safe the result of a strip_tags() call without escaping it first, for example with django.utils.html.escape.
Key and index lookups for django.contrib.postgres.fields.JSONField and key lookups for ~django.contrib.postgres.fields.HStoreField were subject to SQL injection, using a suitably crafted dictionary, with dictionary expansion, as the **kwargs passed to QuerySet.filter().
If passed certain inputs, django.utils.encoding.uri_to_iri could lead to significant memory usage due to excessive recursion when re-percent-encoding invalid UTF-8 octet sequences.
uri_to_iri() now avoids recursion when re-percent-encoding invalid UTF-8 octet sequences.
One column per quarter.
CVE-2019-12781: Incorrect HTTP detection with reverse-proxy connecting via HTTPS
July 1, 2019
Django 2.1.10 fixes a security issue in 2.1.9.
When deployed behind a reverse-proxy connecting to Django via HTTPS, django.http.HttpRequest.scheme would incorrectly detect client requests made via HTTP as using HTTPS. This entails incorrect results for ~django.http.HttpRequest.is_secure, and ~django.http.HttpRequest.build_absolute_uri, and that HTTP requests would not be redirected to HTTPS in accordance with SECURE_SSL_REDIRECT.
HttpRequest.scheme now respects SECURE_PROXY_SSL_HEADER, if it is configured, and the appropriate header is set on the request, for both HTTP and HTTPS requests.
If you deploy Django behind a reverse-proxy that forwards HTTP requests, and that connects to Django via HTTPS, be sure to verify that your application correctly handles code paths relying on scheme, is_secure(), build_absolute_uri(), and SECURE_SSL_REDIRECT.
CVE-2019-12308: AdminURLFieldWidget XSS
June 3, 2019
Django 2.1.9 fixes security issues in 2.1.8.
The clickable "Current URL" link generated by AdminURLFieldWidget displayed the provided value without validating it as a safe URL. Thus, an unvalidated value stored in the database, or a value provided as a URL query parameter payload, could result in an clickable JavaScript link.
AdminURLFieldWidget now validates the provided value using ~django.core.validators.URLValidator before displaying the clickable link. You may customize the validator by passing a validator_class kwarg to AdminURLFieldWidget.__init__(), e.g. when using ~django.contrib.admin.ModelAdmin.formfield_overrides.
jQuery before 3.4.0, mishandles jQuery.extend(true, {}, ...) because of Object.prototype pollution. If an unsanitized source object contained an enumerable __proto__ property, it could extend the native Object.prototype.
The bundled version of jQuery used by the Django admin has been patched to allow for the select2 library's use of jQuery.extend().
Django 2.1.8 fixes a bug in 2.1.7.
April 1, 2019
Django 2.1.8 fixes a bug in 2.1.7.
ManyToManyField's implicit through model
from being editable if the user only has the view permission
(:ticket:30289).Django 2.1.7 fixes a packaging error in 2.1.6.
February 11, 2019
Django 2.1.7 fixes a packaging error in 2.1.6.
30175).CVE-2019-3498: Content spoofing possibility in the default 404 page
January 4, 2019
Django 2.1.5 fixes a security issue and several bugs in 2.1.4.
An attacker could craft a malicious URL that could make spoofed content appear
on the default page generated by the django.views.defaults.page_not_found()
view.
The URL path is no longer displayed in the default 404 template and the
request_path context variable is now quoted to fix the issue for custom
templates that use the path.
Fixed compatibility with mysqlclient 1.3.14 (:ticket:30013).
Fixed a schema corruption issue on SQLite 3.26+. You might have to drop and
rebuild your SQLite database if you applied a migration while using an older
version of Django with SQLite 3.26 or later (:ticket:29182).
Prevented SQLite schema alterations while foreign key checks are enabled to
avoid the possibility of schema corruption (:ticket:30023).
Fixed a regression in Django 2.1.4 (which enabled keep-alive connections)
where request body data isn't properly consumed for such connections
(:ticket:30015).
Fixed a regression in Django 2.1.4 where
InlineModelAdmin.has_change_permission() is incorrectly called with a
non-None obj argument during an object add (:ticket:30050).
Django 2.1.4 fixes several bugs in 2.1.3.
December 3, 2018
Django 2.1.4 fixes several bugs in 2.1.3.
Corrected the default password list that CommonPasswordValidator uses by
lowercasing all passwords to match the format expected by the validator
(:ticket:29952).
Prevented repetitive calls to geos_version_tuple() in the WKBWriter
class in an attempt to fix a random crash involving LooseVersion
(:ticket:29959).
Fixed keep-alive support in runserver after it was disabled to fix
another issue in Django 2.0 (:ticket:29849).
Fixed admin view-only change form crash when using
ModelAdmin.prepopulated_fields (:ticket:29929).
Fixed "Please correct the errors below" error message when editing an object
in the admin if the user only has the "view" permission on inlines
(:ticket:29930).
Django 2.1.3 fixes several bugs in 2.1.2.
November 1, 2018
Django 2.1.3 fixes several bugs in 2.1.2.
Fixed a regression in Django 2.0 where combining Q objects with __in
lookups and lists crashed (:ticket:29838).
Fixed a regression in Django 1.11 where django-admin shell may hang
on startup (:ticket:29774).
Fixed a regression in Django 2.0 where test databases aren't reused with
manage.py test --keepdb on MySQL (:ticket:29827).
Fixed a regression where cached foreign keys that use to_field were
incorrectly cleared in Model.save() (:ticket:29896).
Fixed a regression in Django 2.0 where FileSystemStorage crashes with
FileExistsError if concurrent saves try to create the same directory
(:ticket:29890).
CVE-2018-16984: Password hash disclosure to "view only" admin users
October 1, 2018
Django 2.1.2 fixes a security issue and several bugs in 2.1.1. Also, the latest string translations from Transifex are incorporated.
If an admin user has the change permission to the user model, only part of the password hash is displayed in the change form. Admin users with the view (but not change) permission to the user model were displayed the entire hash. While it's typically infeasible to reverse a strong password hash, if your site uses weaker password hashing algorithms such as MD5 or SHA1, it could be a problem.
Fixed a regression where nonexistent joins in F() no longer raised
FieldError (:ticket:29727).
Fixed a regression where files starting with a tilde or underscore weren't
ignored by the migrations loader (:ticket:29749).
Made migrations detect changes to Meta.default_related_name
(:ticket:29755).
Added compatibility for cx_Oracle 7 (:ticket:29759).
Fixed a regression in Django 2.0 where unique index names weren't quoted
(:ticket:29778).
Fixed a regression where sliced queries with multiple columns with the same
name crashed on Oracle 12.1 (:ticket:29630).
Fixed a crash when a user with the view (but not change) permission made a
POST request to an admin user change form (:ticket:29809).
Django 2.1.1 fixes several bugs in 2.1.
August 31, 2018
Django 2.1.1 fixes several bugs in 2.1.
Fixed a race condition in QuerySet.update_or_create() that could result
in data loss (:ticket:29499).
Fixed a regression where QueryDict.urlencode() crashed if the dictionary
contains a non-string value (:ticket:29627).
Fixed a regression in Django 2.0 where using manage.py test --keepdb
fails on PostgreSQL if the database exists and the user doesn't have
permission to create databases (:ticket:29613).
Fixed a regression in Django 2.0 where combining Q objects with __in
lookups and lists crashed (:ticket:29643).
Fixed translation failure of DurationField's "overflow" error message
(:ticket:29623).
Fixed a regression where the admin change form crashed if the user doesn't
have the 'add' permission to a model that uses TabularInline
(:ticket:29637).
Fixed a regression where a related_query_name reverse accessor wasn't set
up when a GenericRelation is declared on an abstract base model
(:ticket:29653).
Fixed the test client's JSON serialization of a request data dictionary for
structured content type suffixes (:ticket:29662).
Made the admin change view redirect to the changelist view after a POST if
the user has the 'view' permission (:ticket:29663).
Fixed admin change view crash for view-only users if the form has an extra
form field (:ticket:29682).
Fixed a regression in Django 2.0.5 where QuerySet.values() or
values_list() after combining querysets with extra() with
union(), difference(), or intersection() crashed due to
mismatching columns (:ticket:29694).
Fixed crash if InlineModelAdmin.has_add_permission() doesn't accept the
obj argument (:ticket:29723).
- Django 2.1.15 release notes - Django 2.1.14 release notes - Django 2.1.13 release notes - Django 2.1.12 release notes - Django 2.1.11 release notes
Django 2.1.15 release notes
Django 2.1.14 release notes
Django 2.1.13 release notes
Django 2.1.12 release notes
Django 2.1.11 release notes
Django 2.1.10 release notes
Django 2.1.9 release notes
Django 2.1.8 release notes
Django 2.1.7 release notes
Django 2.1.6 release notes
Django 2.1.5 release notes
Django 2.1.4 release notes
Django 2.1.3 release notes
Django 2.1.2 release notes
Django 2.1.1 release notes
Django 2.1 release notes
August 1, 2018
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 from Django 2.0 or earlier. We've dropped some features that have reached the end of their deprecation cycle, and we've begun the deprecation process for some features.
See the /howto/upgrade-version guide if you're updating an existing project.
Django 2.1 supports Python 3.5, 3.6, and 3.7. Django 2.0 is the last version to support Python 3.4. We highly recommend and only officially support the latest release of each series.
A "view" permission is added to the model Meta.default_permissions. The new permissions will be created automatically when running migrate.
This allows giving users read-only access to models in the admin. .ModelAdmin.has_view_permission is new. The implementation is backwards compatible in that there isn't a need to assign the "view" permission to allow users who have the "change" permission to edit objects.
There are a couple of backwards incompatible considerations.
.ModelAdmin.search_fields now accepts any lookup such as field__exact.
jQuery is upgraded from version 2.2.3 to 3.3.1.
The new .ModelAdmin.delete_queryset method allows customizing the deletion process of the "delete selected objects" action.
You can now override the default admin site.
The new .ModelAdmin.sortable_by attribute and .ModelAdmin.get_sortable_by method allow limiting the columns that can be sorted in the change list page.
The admin_order_field attribute for elements in .ModelAdmin.list_display may now be a query expression.
The new .ModelAdmin.get_deleted_objects method allows customizing the deletion process of the delete view and the "delete selected" action.
The actions.html, change_list_results.html, date_hierarchy.html, pagination.html, prepopulated_fields_js.html, search_form.html, and submit_line.html templates can now be overridden per app or per model (besides overridden globally).
The admin change list and change form object tools can now be overridden per app, per model, or globally with change_list_object_tools.html and change_form_object_tools.html templates.
.InlineModelAdmin.has_add_permission is now passed the parent object as the second positional argument, obj.
Admin actions may now specify permissions to limit their availability to certain users.
createsuperuser now gives a prompt to allow bypassing the AUTH_PASSWORD_VALIDATORS checks.
The new .GEOSGeometry.buffer_with_style method is a version of ~.GEOSGeometry.buffer that allows customizing the style of the buffer.
~django.contrib.gis.forms.widgets.OpenLayersWidget is now based on OpenLayers 4.6.5 (previously 3.20.1).
Added the SESSION_COOKIE_SAMESITE setting to set the SameSite cookie flag on session cookies.
The local-memory cache backend now uses a least-recently-used (LRU) culling strategy rather than a pseudo-random one.
The new ~django.core.cache.cache.touch method of the low-level cache API updates the timeout of cache keys.
Added the CSRF_COOKIE_SAMESITE setting to set the SameSite cookie flag on CSRF cookies.
The widget for ImageField now renders with the HTML attribute accept="image/*".
Added the ~django.utils.translation.get_supported_language_variant function.
Untranslated strings for territorial language variants now use the translations of the generic language. For example, untranslated pt_BR strings use pt translations.
The new inspectdb --include-views option allows creating models for database views.
The ~django.core.management.BaseCommand class now uses a custom help formatter so that the standard options like --verbosity or --settings appear last in the help output, giving a more prominent position to subclassed command's options.
Added support for serialization of functools.partialmethod objects.
To support frozen environments, migrations may be loaded from .pyc files.
Models can now use __init_subclass__() from 487.
A BinaryField may now be set to editable=True if you wish to include it in model forms.
A number of new text database functions are added: ~django.db.models.functions.Chr, ~django.db.models.functions.Left, ~django.db.models.functions.LPad, ~django.db.models.functions.LTrim, ~django.db.models.functions.Ord, ~django.db.models.functions.Repeat, ~django.db.models.functions.Replace, ~django.db.models.functions.Right, ~django.db.models.functions.RPad, ~django.db.models.functions.RTrim, and ~django.db.models.functions.Trim.
The new ~django.db.models.functions.TruncWeek function truncates ~django.db.models.DateField and ~django.db.models.DateTimeField to the Monday of a week.
Query expressions can now be negated using a minus sign.
.QuerySet.order_by and distinct(*fields) now support using field transforms.
~django.db.models.BooleanField can now be null=True. This is encouraged instead of NullBooleanField, which will likely be deprecated in the future.
The new .QuerySet.explain method displays the database's execution plan of a queryset's query.
.QuerySet.raw now supports ~.QuerySet.prefetch_related.
Added .HttpRequest.get_full_path_info.
Added the samesite argument to .HttpResponse.set_cookie to allow setting the SameSite cookie flag.
The new as_attachment argument for ~django.http.FileResponse sets the Content-Disposition header to make the browser ask if the user wants to download the file. FileResponse also tries to set the Content-Type and Content-Length headers where appropriate.
The new json_script filter safely outputs a Python object as JSON, wrapped in a <script> tag, ready for use with JavaScript.
Added test ~django.test.Client support for 307 and 308 redirects.
The test ~django.test.Client now serializes a request data dictionary as JSON if content_type='application/json'. You can customize the JSON encoder with test client's json_encoder parameter.
The new .SimpleTestCase.assertWarnsMessage method is a simpler version of ~unittest.TestCase.assertWarnsRegex.
This section describes changes that may be needed in third-party database backends.
To adhere to 249, exceptions where a database doesn't support a feature are changed from NotImplementedError to django.db.NotSupportedError.
Renamed the allow_sliced_subqueries database feature flag to allow_sliced_subqueries_with_in.
DatabaseOperations.distinct_sql() now requires an additional params argument and returns a tuple of SQL and parameters instead of an SQL string.
DatabaseFeatures.introspected_boolean_field_type is changed from a method to a property.
Support for SpatiaLite 4.0 is removed.
The end of upstream support for MySQL 5.5 is December 2018. Django 2.1 supports MySQL 5.6 and higher.
The end of upstream support for PostgreSQL 9.3 is September 2018. Django 2.1 supports PostgreSQL 9.4 and higher.
If you used bcrypt with Django 1.4 or 1.5 (before BCryptSHA256PasswordHasher was added in Django 1.6), you might have some passwords that use the BCryptPasswordHasher hasher.
You can check if that's the case like this:
from django.contrib.auth import get_user_model User = get_user_model() User.objects.filter(password__startswith="bcrypt$$")
If you want to continue to allow those passwords to be used, you'll have to define the PASSWORD_HASHERS setting (if you don't already) and include 'django.contrib.auth.hashers.BCryptPasswordHasher'.
To fix the lack of <label> when using RadioSelect and CheckboxSelectMultiple with MultiWidget, the wrap_label context variable now appears as an attribute of each option. For example, in a custom input_option.html template, change {% if wrap_label %} to {% if widget.wrap_label %}.
The cookies used for django.contrib.sessions, django.contrib.messages, and Django's CSRF protection now set the SameSite flag to Lax by default. Browsers that respect this flag won't send these cookies on cross-origin requests. If you rely on the old behavior, set the SESSION_COOKIE_SAMESITE and/or CSRF_COOKIE_SAMESITE setting to None.
With the new "view" permission, existing custom admin forms may raise errors when a user doesn't have the change permission because the form might access nonexistent fields. Fix this by overriding .ModelAdmin.get_form and checking if the user has the "change" permissions and returning the default form if not:
class MyAdmin(admin.ModelAdmin):
def get_form(self, request, obj=None, **kwargs):
if not self.has_change_permission(request, obj):
return super().get_form(request, obj, **kwargs)
return CustomForm
If you have a custom permission with a codename of the form view_<modelname>, the new view permission handling in the admin will allow view access to the changelist and detail pages for those models. If this is unwanted, you must change your custom permission codename.
The minimum supported version of mysqlclient is increased from 1.3.3 to 1.3.7.
Support for SQLite < 3.7.15 is removed.
The date format of Set-Cookie's Expires directive is changed to follow 7231#section-7.1.1.1 instead of Netscape's cookie standard. Hyphens present in dates like Tue, 25-Dec-2018 22:26:13 GMT are removed. This change should be merely cosmetic except perhaps for antiquated browsers that don't parse the new format.
allowed_hosts is now a required argument of private API django.utils.http.is_safe_url().
The multiple attribute rendered by the ~django.forms.SelectMultiple widget now uses HTML5 boolean syntax rather than XHTML's multiple="multiple".
HTML rendered by form widgets no longer includes a closing slash on void elements, e.g. <br>. This is incompatible within XHTML, although some widgets already used aspects of HTML5 such as boolean attributes.
The value of ~django.forms.SelectDateWidget's empty options is changed from 0 to an empty string, which mainly may require some adjustments in tests that compare HTML.
.User.has_usable_password and the ~django.contrib.auth.hashers.is_password_usable function no longer return False if the password is None or an empty string, or if the password uses a hasher that's not in the PASSWORD_HASHERS setting. This undocumented behavior was a regression in Django 1.6 and prevented users with such passwords from requesting a password reset. Audit your code to confirm that your usage of these APIs don't rely on the old behavior.
Since migrations are now loaded from .pyc files, you might need to delete them if you're working in a mixed Python 2 and Python 3 environment.
Using None as a django.contrib.postgres.fields.JSONField lookup value now matches objects that have the specified key and a null value rather than objects that don't have the key.
The admin CSS class field-box is renamed to fieldBox to prevent conflicts with the class given to model fields named "box".
Since the admin's actions.html, change_list_results.html, date_hierarchy.html, pagination.html, prepopulated_fields_js.html, search_form.html, and submit_line.html templates can now be overridden per app or per model, you may need to rename existing templates with those names that were written for a different purpose.
QuerySet.raw() now caches its results like regular querysets. Use iterator() if you don't want caching.
The database router allow_relation method is called in more cases. Improperly written routers may need to be updated accordingly.
Translations are no longer deactivated before running management commands. If your custom command requires translations to be deactivated (for example, to insert untranslated content into the database), use the new @no_translations decorator.
Management commands no longer allow the abbreviated forms of the --settings and --pythonpath arguments.
The private django.db.models.sql.constants.QUERY_TERMS constant is removed. The ~.RegisterLookupMixin.get_lookup and ~.RegisterLookupMixin.get_lookups methods of the Lookup Registration API may be suitable alternatives. Compared to the QUERY_TERMS constant, they allow your code to also account for any custom lookups that have been registered.
Compatibility with py-bcrypt is removed as it's unmaintained. Use bcrypt instead.
The ForceRHR GIS function is deprecated in favor of the new ~django.contrib.gis.db.models.functions.ForcePolygonCW function.
django.utils.http.cookie_date() is deprecated in favor of ~django.utils.http.http_date, which follows the format of the latest RFC.
{% load staticfiles %} and {% load admin_static %} are deprecated in favor of {% load static %}, which works the same.
django.contrib.staticfiles.templatetags.static() is deprecated in favor of django.templatetags.static.static().
Support for .InlineModelAdmin.has_add_permission methods that don't accept obj as the second positional argument will be removed in Django 3.0.
These features have reached the end of their deprecation cycle and are removed in Django 2.1. See deprecated-features-1.11 for details, including how to remove usage of these features.
contrib.auth.views.login(), logout(), password_change(), password_change_done(), password_reset(), password_reset_done(), password_reset_confirm(), and password_reset_complete() are removed.
The extra_context parameter of contrib.auth.views.logout_then_login() is removed.
django.test.runner.setup_databases() is removed.
django.utils.translation.string_concat() is removed.
django.core.cache.backends.memcached.PyLibMCCache no longer supports passing pylibmc behavior settings as top-level attributes of OPTIONS.
The host parameter of django.utils.http.is_safe_url() is removed.
Silencing of exceptions raised while rendering the {% include %} template tag is removed.
DatabaseIntrospection.get_indexes() is removed.
The authenticate() method of authentication backends requires request as the first positional argument.
The django.db.models.permalink() decorator is removed.
The USE_ETAGS setting is removed. CommonMiddleware and django.utils.cache.patch_response_headers() no longer set ETags.
The Model._meta.has_auto_field attribute is removed.
url()'s support for inline flags in regular expression groups ((?i), (?L), (?m), (?s), and (?u)) is removed.
Support for Widget.render() methods without the renderer argument is removed.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Django 2.0.13 fixes a regression in 2.0.12/2.0.11.
February 12, 2019
Django 2.0.13 fixes a regression in 2.0.12/2.0.11.
django.utils.numberformat.format_number() when the number
has over 200 digits (:ticket:30177).Django 2.0.12 fixes a packaging error in 2.0.11.
February 11, 2019
Django 2.0.12 fixes a packaging error in 2.0.11.
30175).CVE-2019-3498: Content spoofing possibility in the default 404 page
January 4, 2019
Django 2.0.10 fixes a security issue and several bugs in 2.0.9.
An attacker could craft a malicious URL that could make spoofed content appear
on the default page generated by the django.views.defaults.page_not_found()
view.
The URL path is no longer displayed in the default 404 template and the
request_path context variable is now quoted to fix the issue for custom
templates that use the path.
Prevented repetitive calls to geos_version_tuple() in the WKBWriter
class in an attempt to fix a random crash involving LooseVersion since
Django 2.0.6 (:ticket:29959).
Fixed a schema corruption issue on SQLite 3.26+. You might have to drop and
rebuild your SQLite database if you applied a migration while using an older
version of Django with SQLite 3.26 or later (:ticket:29182).
Prevented SQLite schema alterations while foreign key checks are enabled to
avoid the possibility of schema corruption (:ticket:30023).
Django 2.0.9 fixes a data loss bug in 2.0.8.
October 1, 2018
Django 2.0.9 fixes a data loss bug in 2.0.8.
QuerySet.update_or_create() that could result
in data loss (:ticket:29499).CVE-2018-14574: Open redirect possibility in CommonMiddleware
August 1, 2018
Django 2.0.8 fixes a security issue and several bugs in 2.0.7.
If the ~django.middleware.common.CommonMiddleware and the APPEND_SLASH setting are both enabled, and if the project has a URL pattern that accepts any path ending in a slash (many content management systems have such a pattern), then a request to a maliciously crafted URL of that site could lead to a redirect to another site, enabling phishing and other attacks.
CommonMiddleware now escapes leading slashes to prevent redirects to other domains.
Fixed a regression in Django 2.0.7 that broke the regex lookup on MariaDB (even though MariaDB isn't officially supported) (29544).
Fixed a regression where django.template.Template crashed if the template_string argument is lazy (29617).
Django 2.0.7 fixes several bugs in 2.0.6.
July 2, 2018
Django 2.0.7 fixes several bugs in 2.0.6.
Fixed admin changelist crash when using a query expression without asc()
or desc() in the page's ordering (:ticket:29428).
Fixed admin check crash when using a query expression in
ModelAdmin.ordering (:ticket:29428).
Fixed __regex and __iregex lookups with MySQL 8 (:ticket:29451).
Fixed migrations crash with namespace packages on Python 3.7
(:ticket:28814).
Django 2.0.6 fixes several bugs in 2.0.5.
June 1, 2018
Django 2.0.6 fixes several bugs in 2.0.5.
Fixed a regression that broke custom template filters that use decorators
(:ticket:29400).
Fixed detection of custom URL converters in included patterns
(:ticket:29415).
Fixed a regression that added an unnecessary subquery to the GROUP BY
clause on MySQL when using a RawSQL annotation (:ticket:29416).
Fixed WKBWriter.write() and write_hex() for empty polygons on
GEOS 3.6.1+ (:ticket:29460).
Fixed a regression in Django 1.10 that could result in large memory usage
when making edits using ModelAdmin.list_editable (:ticket:28462).
Django 2.0.5 fixes several bugs in 2.0.4.
May 1, 2018
Django 2.0.5 fixes several bugs in 2.0.4.
Corrected the import paths that inspectdb generates for
django.contrib.postgres fields (:ticket:29307).
Fixed a regression in Django 1.11.8 where altering a field with a unique
constraint may drop and rebuild more foreign keys than necessary
(:ticket:29193).
Fixed crashes in django.contrib.admindocs when a view is a callable
object, such as django.contrib.syndication.views.Feed (:ticket:29296).
Fixed a regression in Django 2.0.4 where QuerySet.values() or
values_list() after combining an annotated and unannotated queryset with
union(), difference(), or intersection() crashed due to
mismatching columns (:ticket:29286).
Django 2.0.4 fixes several bugs in 2.0.3.
April 2, 2018
Django 2.0.4 fixes several bugs in 2.0.3.
Fixed a crash when filtering with an Exists() annotation of a queryset
containing a single field (:ticket:29195).
Fixed admin autocomplete widget's translations for zh-hans and
zh-hant languages (:ticket:29213).
Corrected admin's autocomplete widget to add a space after custom classes
(:ticket:29221).
Fixed PasswordResetConfirmView crash when using a user model with a
UUIDField primary key and the reset URL contains an encoded primary key
value that decodes to an invalid UUID (:ticket:29206).
Fixed a regression in Django 1.11.8 where combining two annotated
values_list() querysets with union(), difference(), or
intersection() crashed due to mismatching columns (:ticket:29229).
Fixed a regression in Django 1.11 where an empty choice could be initially
selected for the SelectMultiple and CheckboxSelectMultiple widgets
(:ticket:29273).
Fixed a regression in Django 2.0 where OpenLayersWidget deserialization
ignored the widget map's SRID and assumed 4326 (WGS84) (:ticket:29116).
CVE-2018-7536: Denial-of-service possibility in urlize and urlizetrunc template filters
March 6, 2018
Django 2.0.3 fixes two security issues and several bugs in 2.0.2. Also, the latest string translations from Transifex are incorporated.
urlize and urlizetrunc template filtersThe django.utils.html.urlize() function was extremely slow to evaluate
certain inputs due to catastrophic backtracking vulnerabilities in two regular
expressions. The urlize() function is used to implement the urlize and
urlizetrunc template filters, which were thus vulnerable.
The problematic regular expressions are replaced with parsing logic that behaves similarly.
truncatechars_html and truncatewords_html template filtersIf django.utils.text.Truncator's chars() and words() methods were
passed the html=True argument, they were extremely slow to evaluate certain
inputs due to a catastrophic backtracking vulnerability in a regular
expression. The chars() and words() methods are used to implement the
truncatechars_html and truncatewords_html template filters, which were
thus vulnerable.
The backtracking problem in the regular expression is fixed.
Fixed a regression that caused sliced QuerySet.distinct().order_by()
followed by count() to crash (:ticket:29108).
Prioritized the datetime and time input formats without %f for the Thai
locale to fix the admin time picker widget displaying "undefined"
(:ticket:29109).
Fixed crash with QuerySet.order_by(Exists(...)) (:ticket:29118).
Made Q.deconstruct() deterministic with multiple keyword arguments
(:ticket:29125). You may need to modify Q's in existing migrations, or
accept an autogenerated migration.
Fixed a regression where a When() expression with a list argument crashes
(:ticket:29166).
Fixed crash when using a Window() expression in a subquery
(:ticket:29172).
Fixed AbstractBaseUser.normalize_username() crash if the username
argument isn't a string (:ticket:29176).
CVE-2018-6188: Information leakage in AuthenticationForm
February 1, 2018
Django 2.0.2 fixes a security issue and several bugs in 2.0.1.
A regression in Django 1.11.8 made ~django.contrib.auth.forms.AuthenticationForm run its confirm_login_allowed() method even if an incorrect password is entered. This can leak information about a user, depending on what messages confirm_login_allowed() raises. If confirm_login_allowed() isn't overridden, an attacker enter an arbitrary username and see if that user has been set to is_active=False. If confirm_login_allowed() is overridden, more sensitive details could be leaked.
This issue is fixed with the caveat that AuthenticationForm can no longer raise the "This account is inactive." error if the authentication backend rejects inactive users (the default authentication backend, ModelBackend, has done that since Django 1.10). This issue will be revisited for Django 2.1 as a fix to address the caveat will likely be too invasive for inclusion in older versions.
Fixed hidden content at the bottom of the "The install worked successfully!" page for some languages (28885).
Fixed incorrect foreign key nullification if a model has two foreign keys to the same model and a target model is deleted (29016).
Fixed regression in the use of QuerySet.values_list(..., flat=True) followed by annotate() (29067).
Fixed a regression where a queryset that annotates with geometry objects crashes (29054).
Fixed a regression where contrib.auth.authenticate() crashes if an authentication backend doesn't accept request and a later one does (29071).
Fixed a regression where makemigrations crashes if a migrations directory doesn't have an __init__.py file (29091).
Fixed crash when entering an invalid uuid in ModelAdmin.raw_id_fields (29094).
Django 2.0.1 fixes several bugs in 2.0.
January 1, 2018
Django 2.0.1 fixes several bugs in 2.0.
Fixed a regression in Django 1.11 that added newlines between
MultiWidget's subwidgets (:ticket:28890).
Fixed incorrect class-based model index name generation for models with
quoted db_table (:ticket:28876).
Fixed incorrect foreign key constraint name for models with quoted
db_table (:ticket:28876).
Fixed a regression in caching of a GenericForeignKey when the referenced
model instance uses more than one level of multi-table inheritance
(:ticket:28856).
Reallowed filtering a queryset with GeometryField=None (:ticket:28896).
Corrected admin check to allow a OneToOneField in
ModelAdmin.autocomplete_fields (:ticket:28898).
Fixed a regression on SQLite where DecimalField returned a result with
trailing zeros in the fractional part truncated (:ticket:28915).
Fixed crash in the testserver command startup (:ticket:28941).
Fixed crash when coercing a translatable URL pattern to str
(:ticket:28947).
Fixed crash on SQLite when renaming a field in a model referenced by a
ManyToManyField (:ticket:28884).
Fixed a crash when chaining values() or values_list() after
QuerySet.select_for_update(of=(...)) (:ticket:28944).
Fixed admin changelist crash when using a query expression in the page's
ordering (:ticket:28958).
- Django 2.0.13 release notes - Django 2.0.12 release notes - Django 2.0.11 release notes - Django 2.0.10 release notes - Django 2.0.9 release notes -
Django 2.0.13 release notes
Django 2.0.12 release notes
Django 2.0.11 release notes
Django 2.0.10 release notes
Django 2.0.9 release notes
Django 2.0.8 release notes
Django 2.0.7 release notes
Django 2.0.6 release notes
Django 2.0.5 release notes
Django 2.0.4 release notes
Django 2.0.3 release notes
Django 2.0.2 release notes
Django 2.0.1 release notes
Django 2.0 release notes
December 2, 2017
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 from Django 1.11 or earlier. We've dropped some features that have reached the end of their deprecation cycle, and we've begun the deprecation process for some features.
This release starts Django's use of a loose form of semantic versioning, but there aren't any major backwards incompatible changes that might be expected of a 2.0 release. Upgrading should be a similar amount of effort as past feature releases.
See the /howto/upgrade-version guide if you're updating an existing project.
Django 2.0 supports Python 3.4, 3.5, 3.6, and 3.7. We highly recommend and only officially support the latest release of each series.
The Django 1.11.x series is the last to support Python 2.7.
Django 2.0 will be the last release series to support Python 3.4. If you plan a deployment of Python 3.4 beyond the end-of-life for Django 2.0 (April 2019), stick with Django 1.11 LTS (supported until April 2020) instead. Note, however, that the end-of-life for Python 3.4 is March 2019.
Following the release of Django 2.0, we suggest that third-party app authors drop support for all versions of Django prior to 1.11. At that time, you should be able to run your package's tests using python -Wd so that deprecation warnings do appear. After making the deprecation warning fixes, your app should be compatible with Django 2.0.
The new django.urls.path function allows a simpler, more readable URL routing syntax. For example, this example from previous Django releases:
url(r"^articles/(?P<year>[0-9]{4})/$", views.year_archive),
could be written as:
path("articles/<int:year>/", views.year_archive),
The new syntax supports type coercion of URL parameters. In the example, the view will receive the year keyword argument as an integer rather than as a string. Also, the URLs that will match are slightly less constrained in the rewritten example. For example, the year 10000 will now match since the year integers aren't constrained to be exactly four digits long as they are in the regular expression.
The django.conf.urls.url() function from previous versions is now available as django.urls.re_path. The old location remains for backwards compatibility, without an imminent deprecation. The old django.conf.urls.include() function is now importable from django.urls so you can use from django.urls import include, path, re_path in your URLconfs.
The /topics/http/urls document is rewritten to feature the new syntax and provide more details.
The admin is now responsive and supports all major mobile devices. Older browsers may experience varying levels of graceful degradation.
The new ~django.db.models.expressions.Window expression allows adding an OVER clause to querysets. You can use window functions and aggregate functions in the expression.
The new .ModelAdmin.autocomplete_fields attribute and .ModelAdmin.get_autocomplete_fields method allow using a Select2 search widget for ForeignKey and ManyToManyField.
The default iteration count for the PBKDF2 password hasher is increased from 36,000 to 100,000.
Added MySQL support for the ~django.contrib.gis.db.models.functions.AsGeoJSON function, ~django.contrib.gis.db.models.functions.GeoHash function, ~django.contrib.gis.db.models.functions.IsValid function, isvalid lookup, and distance lookups.
Added the ~django.contrib.gis.db.models.functions.Azimuth and ~django.contrib.gis.db.models.functions.LineLocatePoint functions, supported on PostGIS and SpatiaLite.
Any ~django.contrib.gis.geos.GEOSGeometry imported from GeoJSON now has its SRID set.
Added the .OSMWidget.default_zoom attribute to customize the map's default zoom level.
Made metadata readable and editable on rasters through the ~django.contrib.gis.gdal.GDALRaster.metadata, ~django.contrib.gis.gdal.GDALRaster.info, and ~django.contrib.gis.gdal.GDALBand.metadata attributes.
Allowed passing driver-specific creation options to ~django.contrib.gis.gdal.GDALRaster objects using papsz_options.
Allowed creating ~django.contrib.gis.gdal.GDALRaster objects in GDAL's internal virtual filesystem. Rasters can now be created from and converted to binary data in-memory.
The new GDALBand.color_interp() method returns the color interpretation for the band.
The new distinct argument for ~django.contrib.postgres.aggregates.ArrayAgg determines if concatenated values will be distinct.
The new ~django.contrib.postgres.functions.RandomUUID database function returns a version 4 UUID. It requires use of PostgreSQL's pgcrypto extension which can be activated using the new ~django.contrib.postgres.operations.CryptoExtension migration operation.
django.contrib.postgres.indexes.GinIndex now supports the fastupdate and gin_pending_list_limit parameters.
The new ~django.contrib.postgres.indexes.GistIndex class allows creating GiST indexes in the database. The new ~django.contrib.postgres.operations.BtreeGistExtension migration operation installs the btree_gist extension to add support for operator classes that aren't built-in.
inspectdb can now introspect JSONField and various RangeFields (django.contrib.postgres must be in INSTALLED_APPS).
Added the protocol keyword argument to the ~django.contrib.sitemaps.GenericSitemap constructor.
cache.set_many() now returns a list of keys that failed to be inserted. For the built-in backends, failed inserts can only happen on memcached.
File.open() can be used as a context manager, e.g. with file.open() as f:.
The new date_attrs and time_attrs arguments for ~django.forms.SplitDateTimeWidget and ~django.forms.SplitHiddenDateTimeWidget allow specifying different HTML attributes for the DateInput and TimeInput (or hidden) subwidgets.
The new Form.errors.get_json_data() method returns form errors as a dictionary suitable for including in a JSON response.
The new .ContextMixin.extra_context attribute allows adding context in View.as_view().
inspectdb now translates MySQL's unsigned integer columns to PositiveIntegerField or PositiveSmallIntegerField.
The new makemessages --add-location option controls the comment format in .po files.
loaddata can now read from stdin.
The new diffsettings --output option allows formatting the output in a unified diff format.
On Oracle, inspectdb can now introspect AutoField if the column is created as an identity column.
On MySQL, dbshell now supports client-side TLS certificates.
The new squashmigrations --squashed-name option allows naming the squashed migration.
The new ~django.db.models.functions.StrIndex database function finds the starting index of a string inside another string.
On Oracle, AutoField and BigAutoField are now created as identity columns.
The new chunk_size parameter of .QuerySet.iterator controls the number of rows fetched by the Python database client when streaming results from the database. For databases that don't support server-side cursors, it controls the number of results Django fetches from the database adapter.
.QuerySet.earliest, .QuerySet.latest, and Meta.get_latest_by now allow ordering by several fields.
Added the ~django.db.models.functions.ExtractQuarter function to extract the quarter from ~django.db.models.DateField and ~django.db.models.DateTimeField, and exposed it through the quarter lookup.
Added the ~django.db.models.functions.TruncQuarter function to truncate ~django.db.models.DateField and ~django.db.models.DateTimeField to the first day of a quarter.
Added the ~django.db.models.Index.db_tablespace parameter to class-based indexes.
If the database supports a native duration field (Oracle and PostgreSQL), ~django.db.models.functions.Extract now works with ~django.db.models.DurationField.
Added the of argument to .QuerySet.select_for_update, supported on PostgreSQL and Oracle, to lock only rows from specific tables rather than all selected tables. It may be helpful particularly when ~.QuerySet.select_for_update is used in conjunction with ~.QuerySet.select_related.
The new field_name parameter of .QuerySet.in_bulk allows fetching results based on any unique model field.
.CursorWrapper.callproc now takes an optional dictionary of keyword parameters, if the backend supports this feature. Of Django's built-in backends, only Oracle supports it.
The new connection.execute_wrapper() method allows installing wrappers around execution of database queries.
The new filter argument for built-in aggregates allows adding different conditionals to multiple aggregations over the same fields or relations.
Added support for expressions in Meta.ordering.
The new named parameter of .QuerySet.values_list allows fetching results as named tuples.
The new .FilteredRelation class allows adding an ON clause to querysets.
Added Paginator.get_page() to provide the documented pattern of handling invalid page numbers.
The runserver web server supports HTTP 1.1.
To increase the usefulness of .Engine.get_default in third-party apps, it now returns the first engine if multiple DjangoTemplates engines are configured in TEMPLATES rather than raising ImproperlyConfigured.
Custom template tags may now accept keyword-only arguments.
Added threading support to ~django.test.LiveServerTestCase.
Added settings that allow customizing the test tablespace parameters for Oracle: DATAFILE_SIZE, DATAFILE_TMP_SIZE, DATAFILE_EXTSIZE, and DATAFILE_TMP_EXTSIZE.
The new .ProhibitNullCharactersValidator disallows the null character in the input of the ~django.forms.CharField form field and its subclasses. Null character input was observed from vulnerability scanning tools. Most databases silently discard null characters, but psycopg2 2.7+ raises an exception when trying to save a null character to a char/text field with PostgreSQL.
To support native Python 2 strings, older Django versions had to accept both bytestrings and Unicode strings. Now that Python 2 support is dropped, bytestrings should only be encountered around input/output boundaries (handling of binary fields or HTTP streams, for example). You might have to update your code to limit bytestring usage to a minimum, as Django no longer accepts bytestrings in certain code paths. Python's -b option may help detect that mistake in your code.
For example, reverse() now uses str() instead of force_text() to coerce the args and kwargs it receives, prior to their placement in the URL. For bytestrings, this creates a string with an undesired b prefix as well as additional quotes (str(b'foo') is "b'foo'"). To adapt, call decode() on the bytestring before passing it to reverse().
This section describes changes that may be needed in third-party database backends.
The DatabaseOperations.datetime_cast_date_sql(), datetime_cast_time_sql(), datetime_trunc_sql(), datetime_extract_sql(), and date_interval_sql() methods now return only the SQL to perform the operation instead of SQL and a list of parameters.
Third-party database backends should add a DatabaseWrapper.display_name attribute with the name of the database that your backend works with. Django may use it in various messages, such as in system checks.
The first argument of SchemaEditor._alter_column_type_sql() is now model rather than table.
The first argument of SchemaEditor._create_index_name() is now table_name rather than model.
To enable FOR UPDATE OF support, set DatabaseFeatures.has_select_for_update_of = True. If the database requires that the arguments to OF be columns rather than tables, set DatabaseFeatures.select_for_update_of_column = True.
To enable support for ~django.db.models.expressions.Window expressions, set DatabaseFeatures.supports_over_clause to True. You may need to customize the DatabaseOperations.window_start_rows_start_end() and/or window_start_range_start_end() methods.
Third-party database backends should add a DatabaseOperations.cast_char_field_without_max_length attribute with the database data type that will be used in the ~django.db.models.functions.Cast function for a CharField if the max_length argument isn't provided.
The first argument of DatabaseCreation._clone_test_db() and get_test_db_clone_settings() is now suffix rather than number (in case you want to rename the signatures in your backend for consistency). django.test also now passes those values as strings rather than as integers.
Third-party database backends should add a DatabaseIntrospection.get_sequences() method based on the stub in BaseDatabaseIntrospection.
The end of upstream support for Oracle 11.2 is Dec. 2020. Django 1.11 will be supported until April 2020 which almost reaches this date. Django 2.0 officially supports Oracle 12.1+.
MySQL's default isolation level, repeatable read, may cause data loss in typical Django usage. To prevent that and for consistency with other databases, the default isolation level is now read committed. You can use the DATABASES setting to use a different isolation level, if needed.
A migration for django.contrib.auth.models.User.last_name is included. If you have a custom user model inheriting from AbstractUser, you'll need to generate and apply a database migration for your user model.
If you want to preserve the 30 character limit for last names, use a custom form:
from django.contrib.auth.forms import UserChangeForm
class MyUserChangeForm(UserChangeForm):
last_name = forms.CharField(max_length=30, required=False)
If you wish to keep this restriction in the admin when editing users, set UserAdmin.form to use this form:
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
class MyUserAdmin(UserAdmin):
form = MyUserChangeForm
admin.site.unregister(User)
admin.site.register(User, MyUserAdmin)
Calling QuerySet.reverse() or last() on a sliced queryset leads to unexpected results due to the slice being applied after reordering. This is now prohibited, e.g.:
>>> Model.objects.all()[:2].reverse()
Traceback (most recent call last):
...
TypeError: Cannot reverse a query once a slice has been taken.
To help prevent runtime errors due to incorrect ordering of form field arguments, optional arguments of built-in form fields are no longer accepted as positional arguments. For example:
forms.IntegerField(25, 10)
raises an exception and should be replaced with:
forms.IntegerField(max_value=25, min_value=10)
call_command() now validates that the argument parser of the command being called defines all of the options passed to call_command().
For custom management commands that use options not created using parser.add_argument(), add a stealth_options attribute on the command:
class MyCommand(BaseCommand):
stealth_options = ("option_name", ...)
For example:
models.Index(["headline", "-pub_date"], "index_name")
raises an exception and should be replaced with:
models.Index(fields=["headline", "-pub_date"], name="index_name")
This will appear as a backwards-incompatible change (IntegrityError: FOREIGN KEY constraint failed) if attempting to save an existing model instance that's violating a foreign key constraint.
Foreign keys are now created with DEFERRABLE INITIALLY DEFERRED instead of DEFERRABLE IMMEDIATE. Thus, tables may need to be rebuilt to recreate foreign keys with the new definition, particularly if you're using a pattern like this:
from django.db import transaction
with transaction.atomic():
Book.objects.create(author_id=1)
Author.objects.create(id=1)
If you don't recreate the foreign key as DEFERRED, the first create() would fail now that foreign key constraints are enforced.
Backup your database first! After upgrading to Django 2.0, you can then rebuild tables using a script similar to this:
from django.apps import apps
from django.db import connection
for app in apps.get_app_configs():
for model in app.get_models(include_auto_created=True):
if model._meta.managed and not (model._meta.proxy or model._meta.swapped):
for base in model.__bases__:
if hasattr(base, "_meta"):
base._meta.local_many_to_many = []
model._meta.local_many_to_many = []
with connection.schema_editor() as editor:
editor._remake_table(model)
This script hasn't received extensive testing and needs adaption for various cases such as multiple databases. Feel free to contribute improvements.
In addition, because of a table alteration limitation of SQLite, it's prohibited to perform ~django.db.migrations.operations.RenameModel and ~django.db.migrations.operations.RenameField operations on models or fields referenced by other models in a transaction. In order to allow migrations containing these operations to be applied, you must set the Migration.atomic attribute to False.
The SessionAuthenticationMiddleware class is removed. It provided no functionality since session authentication is unconditionally enabled in Django 1.10.
The default HTTP error handlers (handler404, etc.) are now callables instead of dotted Python path strings. Django favors callable references since they provide better performance and debugging experience.
~django.views.generic.base.RedirectView no longer silences NoReverseMatch if the pattern_name doesn't exist.
When USE_L10N is off, ~django.forms.FloatField and ~django.forms.DecimalField now respect DECIMAL_SEPARATOR and THOUSAND_SEPARATOR during validation. For example, with the settings:
USE_L10N = False USE_THOUSAND_SEPARATOR = True DECIMAL_SEPARATOR = "," THOUSAND_SEPARATOR = "."
an input of "1.345" is now converted to 1345 instead of 1.345.
Subclasses of ~django.contrib.auth.models.AbstractBaseUser are no longer required to implement get_short_name() and get_full_name(). (The base implementations that raise NotImplementedError are removed.) django.contrib.admin uses these methods if implemented but doesn't require them. Third-party apps that use these methods may want to adopt a similar approach.
The FIRST_DAY_OF_WEEK and NUMBER_GROUPING format settings are now kept as integers in JavaScript and JSON i18n view outputs.
~django.test.TransactionTestCase.assertNumQueries now ignores connection configuration queries. Previously, if a test opened a new database connection, those queries could be included as part of the assertNumQueries() count.
The default size of the Oracle test tablespace is increased from 20M to 50M and the default autoextend size is increased from 10M to 25M.
To improve performance when streaming large result sets from the database, .QuerySet.iterator now fetches 2000 rows at a time instead of 100. The old behavior can be restored using the chunk_size parameter. For example:
Book.objects.iterator(chunk_size=100)
Providing unknown package names in the packages argument of the ~django.views.i18n.JavaScriptCatalog view now raises ValueError instead of passing silently.
A model instance's primary key now appears in the default Model.__str__() method, e.g. Question object (1).
makemigrations now detects changes to the model field limit_choices_to option. Add this to your existing migrations or accept an auto-generated migration for fields that use it.
Performing queries that require automatic spatial transformations now raises NotImplementedError on MySQL instead of silently using non-transformed geometries.
django.core.exceptions.DjangoRuntimeWarning is removed. It was only used in the cache backend as an intermediate class in CacheKeyWarning's inheritance of RuntimeWarning.
Renamed BaseExpression._output_field to output_field. You may need to update custom expressions.
In older versions, forms and formsets combine their Media with widget Media by concatenating the two. The combining now tries to preserve the relative order of elements in each list. MediaOrderConflictWarning is issued if the order can't be preserved.
django.contrib.gis.gdal.OGRException is removed. It's been an alias for GDALException since Django 1.8.
Support for GEOS 3.3.x is dropped.
The way data is selected for GeometryField is changed to improve performance, and in raw SQL queries, those fields must now be wrapped in connection.ops.select. See the Raw queries note in the GIS tutorial for an example.
The context argument of Field.from_db_value() and Expression.convert_value() is unused as it's always an empty dictionary. The signature of both methods is now:
(self, value, expression, connection)
instead of:
(self, value, expression, connection, context)
Support for the old signature in custom fields and expressions remains until Django 3.0.
The django.db.backends.postgresql_psycopg2 module is deprecated in favor of django.db.backends.postgresql. It's been an alias since Django 1.9. This only affects code that imports from the module directly. The DATABASES setting can still use 'django.db.backends.postgresql_psycopg2', though you can simplify that by using the 'django.db.backends.postgresql' name added in Django 1.9.
django.shortcuts.render_to_response() is deprecated in favor of django.shortcuts.render. render() takes the same arguments except that it also requires a request.
The DEFAULT_CONTENT_TYPE setting is deprecated. It doesn't interact well with third-party apps and is obsolete since HTML5 has mostly superseded XHTML.
HttpRequest.xreadlines() is deprecated in favor of iterating over the request.
The field_name keyword argument to .QuerySet.earliest and .QuerySet.latest is deprecated in favor of passing the field names as arguments. Write .earliest('pub_date') instead of .earliest(field_name='pub_date').
These features have reached the end of their deprecation cycle and are removed in Django 2.0.
See deprecated-features-1.9 for details on these changes, including how to remove usage of these features.
The weak argument to django.dispatch.signals.Signal.disconnect() is removed.
django.db.backends.base.BaseDatabaseOperations.check_aggregate_support() is removed.
The django.forms.extras package is removed.
The assignment_tag helper is removed.
The host argument to SimpleTestCase.assertsRedirects() is removed. The compatibility layer which allows absolute URLs to be considered equal to relative ones when the path is identical is also removed.
Field.rel and Field.remote_field.to are removed.
The on_delete argument for ForeignKey and OneToOneField is now required in models and migrations. Consider squashing migrations so that you have fewer of them to update.
django.db.models.fields.add_lazy_relation() is removed.
When time zone support is enabled, database backends that don't support time zones no longer convert aware datetimes to naive values in UTC anymore when such values are passed as parameters to SQL queries executed outside of the ORM, e.g. with cursor.execute().
django.contrib.auth.tests.utils.skipIfCustomUser() is removed.
The GeoManager and GeoQuerySet classes are removed.
The django.contrib.gis.geoip module is removed.
The supports_recursion check for template loaders is removed from:
django.template.engine.Engine.find_template()
django.template.loader_tags.ExtendsNode.find_template()
django.template.loaders.base.Loader.supports_recursion()
django.template.loaders.cached.Loader.supports_recursion()
The load_template and load_template_sources template loader methods are removed.
The template_dirs argument for template loaders is removed:
django.template.loaders.base.Loader.get_template()
django.template.loaders.cached.Loader.cache_key()
django.template.loaders.cached.Loader.get_template()
django.template.loaders.cached.Loader.get_template_sources()
django.template.loaders.filesystem.Loader.get_template_sources()
django.template.loaders.base.Loader.__call__() is removed.
Support for custom error views that don't accept an exception parameter is removed.
The mime_type attribute of django.utils.feedgenerator.Atom1Feed and django.utils.feedgenerator.RssFeed is removed.
The app_name argument to include() is removed.
Support for passing a 3-tuple (including admin.site.urls) as the first argument to include() is removed.
Support for setting a URL instance namespace without an application namespace is removed.
Field._get_val_from_obj() is removed.
django.template.loaders.eggs.Loader is removed.
The current_app parameter to the contrib.auth function-based views is removed.
The callable_obj keyword argument to SimpleTestCase.assertRaisesMessage() is removed.
Support for the allow_tags attribute on ModelAdmin methods is removed.
The enclosure keyword argument to SyndicationFeed.add_item() is removed.
The django.template.loader.LoaderOrigin and django.template.base.StringOrigin aliases for django.template.base.Origin are removed.
See deprecated-features-1.10 for details on these changes.
The makemigrations --exit option is removed.
Support for direct assignment to a reverse foreign key or many-to-many relation is removed.
The get_srid() and set_srid() methods of django.contrib.gis.geos.GEOSGeometry are removed.
The get_x(), set_x(), get_y(), set_y(), get_z(), and set_z() methods of django.contrib.gis.geos.Point are removed.
The get_coords() and set_coords() methods of django.contrib.gis.geos.Point are removed.
The cascaded_union property of django.contrib.gis.geos.MultiPolygon is removed.
django.utils.functional.allow_lazy() is removed.
The shell --plain option is removed.
The django.core.urlresolvers module is removed in favor of its new location, django.urls.
CommaSeparatedIntegerField is removed, except for support in historical migrations.
The template Context.has_key() method is removed.
Support for the django.core.files.storage.Storage.accessed_time(), created_time(), and modified_time() methods is removed.
Support for query lookups using the model name when Meta.default_related_name is set is removed.
The MySQL __search lookup is removed.
The shim for supporting custom related manager classes without a _apply_rel_filters() method is removed.
Using User.is_authenticated() and User.is_anonymous() as methods rather than properties is no longer supported.
The Model._meta.virtual_fields attribute is removed.
The keyword arguments virtual_only in Field.contribute_to_class() and virtual in Model._meta.add_field() are removed.
The javascript_catalog() and json_catalog() views are removed.
django.contrib.gis.utils.precision_wkt() is removed.
In multi-table inheritance, implicit promotion of a OneToOneField to a parent_link is removed.
Support for Widget._format_value() is removed.
FileField methods get_directory_name() and get_filename() are removed.
The mark_for_escaping() function and the classes it uses: EscapeData, EscapeBytes, EscapeText, EscapeString, and EscapeUnicode are removed.
The escape filter now uses django.utils.html.conditional_escape().
Manager.use_for_related_fields is removed.
Model Manager inheritance follows MRO inheritance rules. The requirement to use Meta.manager_inheritance_from_future to opt-in to the behavior is removed.
Support for old-style middleware using settings.MIDDLEWARE_CLASSES is removed.
Nothing published for this version
Nothing published for this version
Nothing published for this version
CVE-2020-9402: Potential SQL injection via tolerance parameter in GIS functions and aggregates on Oracle
March 4, 2020
Django 1.11.29 fixes a security issue in 1.11.28.
tolerance parameter in GIS functions and aggregates on OracleGIS functions and aggregates on Oracle were subject to SQL injection,
using a suitably crafted tolerance.
CVE-2020-7471: Potential SQL injection via StringAgg(delimiter)
February 3, 2020
Django 1.11.28 fixes a security issue in 1.11.27.
~django.contrib.postgres.aggregates.StringAgg aggregation function was subject to SQL injection, using a suitably crafted delimiter.
CVE-2019-19844: Potential account hijack via password reset form
December 18, 2019
Django 1.11.27 fixes a security issue and a data loss bug in 1.11.26.
By submitting a suitably crafted email address making use of Unicode characters, that compared equal to an existing user email when lower-cased for comparison, an attacker could be sent a password reset token for the matched account.
In order to avoid this vulnerability, password reset requests now compare the submitted email using the stricter, recommended algorithm for case-insensitive comparison of two identifiers from Unicode Technical Report 36, section 2.11.2(B)(2). Upon a match, the email containing the reset token will be sent to the email address on record rather than the submitted address.
Fixed a data loss possibility in ~django.contrib.postgres.forms.SplitArrayField. When using with ArrayField(BooleanField()), all values after the first True value were marked as checked instead of preserving passed values (31073).
Django 1.11.26 fixes a regression in 1.11.25.
November 4, 2019
Django 1.11.26 fixes a regression in 1.11.25.
contains, contained_by, has_key,
has_keys, or has_any_keys lookup on
django.contrib.postgres.fields.JSONField, if the right or left hand
side of an expression is a key transform (:ticket:30826).Django 1.11.25 fixes a regression in 1.11.23.
October 1, 2019
Django 1.11.25 fixes a regression in 1.11.23.
Fixed a crash when filtering with a Subquery() annotation of a queryset containing django.contrib.postgres.fields.JSONField or ~django.contrib.postgres.fields.HStoreField (30769).
Django 1.11.24 fixes a regression in 1.11.23.
September 2, 2019
Django 1.11.24 fixes a regression in 1.11.23.
Fixed crash of KeyTransform() for django.contrib.postgres.fields.JSONField and ~django.contrib.postgres.fields.HStoreField when using on expressions with params (30672).
CVE-2019-14232: Denial-of-service possibility in django.utils.text.Truncator
August 1, 2019
Django 1.11.23 fixes security issues in 1.11.22.
If django.utils.text.Truncator's chars() and words() methods were passed the html=True argument, they were extremely slow to evaluate certain inputs due to a catastrophic backtracking vulnerability in a regular expression. The chars() and words() methods are used to implement the truncatechars_html and truncatewords_html template filters, which were thus vulnerable.
The regular expressions used by Truncator have been simplified in order to avoid potential backtracking issues. As a consequence, trailing punctuation may now at times be included in the truncated output.
Due to the behavior of the underlying HTMLParser, django.utils.html.strip_tags would be extremely slow to evaluate certain inputs containing large sequences of nested incomplete HTML entities. The strip_tags() method is used to implement the corresponding striptags template filter, which was thus also vulnerable.
strip_tags() now avoids recursive calls to HTMLParser when progress removing tags, but necessarily incomplete HTML entities, stops being made.
Remember that absolutely NO guarantee is provided about the results of strip_tags() being HTML safe. So NEVER mark safe the result of a strip_tags() call without escaping it first, for example with django.utils.html.escape.
Key and index lookups for django.contrib.postgres.fields.JSONField and key lookups for ~django.contrib.postgres.fields.HStoreField were subject to SQL injection, using a suitably crafted dictionary, with dictionary expansion, as the **kwargs passed to QuerySet.filter().
If passed certain inputs, django.utils.encoding.uri_to_iri could lead to significant memory usage due to excessive recursion when re-percent-encoding invalid UTF-8 octet sequences.
uri_to_iri() now avoids recursion when re-percent-encoding invalid UTF-8 octet sequences.
CVE-2019-12781: Incorrect HTTP detection with reverse-proxy connecting via HTTPS
July 1, 2019
Django 1.11.22 fixes a security issue in 1.11.21.
When deployed behind a reverse-proxy connecting to Django via HTTPS, django.http.HttpRequest.scheme would incorrectly detect client requests made via HTTP as using HTTPS. This entails incorrect results for ~django.http.HttpRequest.is_secure, and ~django.http.HttpRequest.build_absolute_uri, and that HTTP requests would not be redirected to HTTPS in accordance with SECURE_SSL_REDIRECT.
HttpRequest.scheme now respects SECURE_PROXY_SSL_HEADER, if it is configured, and the appropriate header is set on the request, for both HTTP and HTTPS requests.
If you deploy Django behind a reverse-proxy that forwards HTTP requests, and that connects to Django via HTTPS, be sure to verify that your application correctly handles code paths relying on scheme, is_secure(), build_absolute_uri(), and SECURE_SSL_REDIRECT.
CVE-2019-12308: AdminURLFieldWidget XSS
June 3, 2019
Django 1.11.21 fixes a security issue in 1.11.20.
The clickable "Current URL" link generated by AdminURLFieldWidget displayed the provided value without validating it as a safe URL. Thus, an unvalidated value stored in the database, or a value provided as a URL query parameter payload, could result in an clickable JavaScript link.
AdminURLFieldWidget now validates the provided value using ~django.core.validators.URLValidator before displaying the clickable link. You may customize the validator by passing a validator_class kwarg to AdminURLFieldWidget.__init__(), e.g. when using ~django.contrib.admin.ModelAdmin.formfield_overrides.
Django 1.11.20 fixes a packaging error in 1.11.19.
February 11, 2019
Django 1.11.20 fixes a packaging error in 1.11.19.
30175).CVE-2019-3498: Content spoofing possibility in the default 404 page
January 4, 2019
Django 1.11.18 fixes a security issue in 1.11.17.
An attacker could craft a malicious URL that could make spoofed content appear
on the default page generated by the django.views.defaults.page_not_found()
view.
The URL path is no longer displayed in the default 404 template and the
request_path context variable is now quoted to fix the issue for custom
templates that use the path.
Django 1.11.17 fixes several bugs in 1.11.16 and adds compatibility with Python 3.7.
December 3, 2018
Django 1.11.17 fixes several bugs in 1.11.16 and adds compatibility with Python 3.7.
geos_version_tuple() in the WKBWriter
class in an attempt to fix a random crash involving LooseVersion since
Django 1.11.14 (:ticket:29959).Django 1.11.16 fixes a data loss bug in 1.11.15.
October 1, 2018
Django 1.11.16 fixes a data loss bug in 1.11.15.
QuerySet.update_or_create() that could result
in data loss (:ticket:29499).CVE-2018-14574: Open redirect possibility in CommonMiddleware
August 1, 2018
Django 1.11.15 fixes a security issue in 1.11.14.
If the ~django.middleware.common.CommonMiddleware and the APPEND_SLASH setting are both enabled, and if the project has a URL pattern that accepts any path ending in a slash (many content management systems have such a pattern), then a request to a maliciously crafted URL of that site could lead to a redirect to another site, enabling phishing and other attacks.
CommonMiddleware now escapes leading slashes to prevent redirects to other domains.
Django 1.11.14 fixes several bugs in 1.11.13.
July 2, 2018
Django 1.11.14 fixes several bugs in 1.11.13.
Fixed WKBWriter.write() and write_hex() for empty polygons on
GEOS 3.6.1+ (:ticket:29460).
Fixed a regression in Django 1.10 that could result in large memory usage
when making edits using ModelAdmin.list_editable (:ticket:28462).
Django 1.11.13 fixes several bugs in 1.11.12.
May 1, 2018
Django 1.11.13 fixes several bugs in 1.11.12.
Fixed a regression in Django 1.11.8 where altering a field with a unique
constraint may drop and rebuild more foreign keys than necessary
(:ticket:29193).
Fixed crashes in django.contrib.admindocs when a view is a callable
object, such as django.contrib.syndication.views.Feed (:ticket:29296).
Fixed a regression in Django 1.11.12 where QuerySet.values() or
values_list() after combining an annotated and unannotated queryset with
union(), difference(), or intersection() crashed due to
mismatching columns (:ticket:29286).
Django 1.11.12 fixes two bugs in 1.11.11.
April 2, 2018
Django 1.11.12 fixes two bugs in 1.11.11.
Fixed a regression in Django 1.11.8 where combining two annotated
values_list() querysets with union(), difference(), or
intersection() crashed due to mismatching columns (:ticket:29229).
Fixed a regression in Django 1.11 where an empty choice could be initially
selected for the SelectMultiple and CheckboxSelectMultiple widgets
(:ticket:29273).
CVE-2018-7536: Denial-of-service possibility in urlize and urlizetrunc template filters
March 6, 2018
Django 1.11.11 fixes two security issues in 1.11.10.
urlize and urlizetrunc template filtersThe django.utils.html.urlize() function was extremely slow to evaluate
certain inputs due to catastrophic backtracking vulnerabilities in two regular
expressions. The urlize() function is used to implement the urlize and
urlizetrunc template filters, which were thus vulnerable.
The problematic regular expressions are replaced with parsing logic that behaves similarly.
truncatechars_html and truncatewords_html template filtersIf django.utils.text.Truncator's chars() and words() methods were
passed the html=True argument, they were extremely slow to evaluate certain
inputs due to a catastrophic backtracking vulnerability in a regular
expression. The chars() and words() methods are used to implement the
truncatechars_html and truncatewords_html template filters, which were
thus vulnerable.
The backtracking problem in the regular expression is fixed.
CVE-2018-6188: Information leakage in AuthenticationForm
February 1, 2018
Django 1.11.10 fixes a security issue and several bugs in 1.11.9.
A regression in Django 1.11.8 made ~django.contrib.auth.forms.AuthenticationForm run its confirm_login_allowed() method even if an incorrect password is entered. This can leak information about a user, depending on what messages confirm_login_allowed() raises. If confirm_login_allowed() isn't overridden, an attacker enter an arbitrary username and see if that user has been set to is_active=False. If confirm_login_allowed() is overridden, more sensitive details could be leaked.
This issue is fixed with the caveat that AuthenticationForm can no longer raise the "This account is inactive." error if the authentication backend rejects inactive users (the default authentication backend, ModelBackend, has done that since Django 1.10). This issue will be revisited for Django 2.1 as a fix to address the caveat will likely be too invasive for inclusion in older versions.
Fixed incorrect foreign key nullification if a model has two foreign keys to the same model and a target model is deleted (29016).
Fixed a regression where contrib.auth.authenticate() crashes if an authentication backend doesn't accept request and a later one does (29071).
Fixed crash when entering an invalid uuid in ModelAdmin.raw_id_fields (29094).
Django 1.11.9 fixes several bugs in 1.11.8.
January 1, 2018
Django 1.11.9 fixes several bugs in 1.11.8.
Fixed a regression in Django 1.11 that added newlines between
MultiWidget's subwidgets (:ticket:28890).
Fixed incorrect class-based model index name generation for models with
quoted db_table (:ticket:28876).
Fixed incorrect foreign key constraint name for models with quoted
db_table (:ticket:28876).
Fixed a regression in caching of a GenericForeignKey when the referenced
model instance uses more than one level of multi-table inheritance
(:ticket:28856).
Django 1.11.8 fixes several bugs in 1.11.7.
December 2, 2017
Django 1.11.8 fixes several bugs in 1.11.7.
Reallowed, following a regression in Django 1.10, AuthenticationForm to
raise the inactive user error when using ModelBackend (:ticket:28645).
Added support for QuerySet.values() and values_list() for
union(), difference(), and intersection() queries
(:ticket:28781).
Fixed incorrect index name truncation when using a namespaced db_table
(:ticket:28792).
Made QuerySet.iterator() use server-side cursors on PostgreSQL after
values() and values_list() (:ticket:28817).
Fixed crash on SQLite and MySQL when ordering by a filtered subquery that
uses nulls_first or nulls_last (:ticket:28848).
Made query lookups for CICharField, CIEmailField, and CITextField
use a citext cast (:ticket:28702).
Fixed a regression in caching of a GenericForeignKey when the referenced
model instance uses multi-table inheritance (:ticket:28856).
Fixed "Cannot change column 'x': used in a foreign key constraint" crash on
MySQL with a sequence of AlterField and/or RenameField operations in
a migration (:ticket:28305).
Django 1.11.7 fixes several bugs in 1.11.6.
November 1, 2017
Django 1.11.7 fixes several bugs in 1.11.6.
Prevented cache.get_or_set() from caching None if the default
argument is a callable that returns None (:ticket:28601).
Fixed the Basque DATE_FORMAT string (:ticket:28710).
Made QuerySet.reverse() affect nulls_first and nulls_last
(:ticket:28722).
Fixed unquoted table names in Subquery SQL when using OuterRef
(:ticket:28689).
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
- Django 1.11.29 release notes - Django 1.11.28 release notes - Django 1.11.27 release notes - Django 1.11.26 release notes - Django 1.11.25 release n
Django 1.11.29 release notes
Django 1.11.28 release notes
Django 1.11.27 release notes
Django 1.11.26 release notes
Django 1.11.25 release notes
Django 1.11.24 release notes
Django 1.11.23 release notes
Django 1.11.22 release notes
Django 1.11.21 release notes
Django 1.11.20 release notes
Django 1.11.19 release notes
Django 1.11.18 release notes
Django 1.11.17 release notes
Django 1.11.16 release notes
Django 1.11.15 release notes
Django 1.11.14 release notes
Django 1.11.13 release notes
Django 1.11.12 release notes
Django 1.11.11 release notes
Django 1.11.10 release notes
Django 1.11.9 release notes
Django 1.11.8 release notes
Django 1.11.7 release notes
Django 1.11.6 release notes
Django 1.11.5 release notes
Django 1.11.4 release notes
Django 1.11.3 release notes
Django 1.11.2 release notes
Django 1.11.1 release notes
Django 1.11 release notes
Your coding agent can read these notes before it upgrades. Set up the MCP server →