Django 4.2 release notesLien vers cette rubrique
April 3, 2023
Welcome to Django 4.2!
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 4.1 or earlier. We’ve begun the deprecation process for some features.
Voir le guide Mise à jour de Django à une version plus récente si vous mettez à jour un projet existant.
Django 4.2 is designated as a long-term support release. It will receive security updates for at least three years after its release. Support for the previous LTS, Django 3.2, will end in April 2024.
Compatibilité PythonLien vers cette rubrique
Django 4.2 supports Python 3.8, 3.9, 3.10, 3.11, and 3.12 (as of 4.2.8). We highly recommend and only officially support the latest release of each series.
What’s new in Django 4.2Lien vers cette rubrique
Psycopg 3 supportLien vers cette rubrique
Django now supports psycopg version 3.1.8 or higher. To update your code,
install the psycopg library, you don’t need to change the
ENGINE as django.db.backends.postgresql
supports both libraries.
La prise en charge de psycopg2 va certainement être rendue obsolète, puis supprimée dans le futur.
Be aware that psycopg 3 introduces some breaking changes over psycopg2.
As a consequence, you may need to make some changes to account for
differences from psycopg2.
Mitigation for the BREACH attackLien vers cette rubrique
GZipMiddleware now includes a mitigation for
the BREACH attack. It will add up to 100 random bytes to gzip responses to make
BREACH attacks harder. Read more about the mitigation technique in the Heal
The Breach (HTB) paper.
In-memory file storageLien vers cette rubrique
The new django.core.files.storage.InMemoryStorage class provides a
non-persistent storage useful for speeding up tests by avoiding disk access.
Custom file storagesLien vers cette rubrique
The new STORAGES setting allows configuring multiple custom file
storage backends. It also controls storage engines for managing
files (the "default" key) and static files (the "staticfiles" key).
The old DEFAULT_FILE_STORAGE and STATICFILES_STORAGE settings are
deprecated as of this release.
Fonctionnalités mineuresLien vers cette rubrique
django.contrib.adminLien vers cette rubrique
The light or dark color theme of the admin can now be toggled in the UI, as well as being set to follow the system setting.
The admin’s font stack now prefers system UI fonts and no longer requires downloading fonts. Additionally, CSS variables are available to more easily override the default font families.
The admin/delete_confirmation.html template now has some additional blocks and scripting hooks to ease customization.
The chosen options of
filter_horizontalandfilter_verticalwidgets are now filterable.The
admin/base.htmltemplate now has a new blocknav-breadcrumbswhich contains the navigation landmark and thebreadcrumbsblock.ModelAdmin.list_editablenow uses atomic transactions when making edits.jQuery is upgraded from version 3.6.0 to 3.6.4.
django.contrib.authLien vers cette rubrique
The default iteration count for the PBKDF2 password hasher is increased from 390,000 to 600,000.
UserCreationFormnow saves many-to-many form fields for a custom user model.The new
BaseUserCreationFormis now the recommended base class for customizing the user creation form.
django.contrib.gisLien vers cette rubrique
The GeoJSON serializer now outputs the
idkey for serialized features, which defaults to the primary key of objects.The
GDALRasterclass now supportspathlib.Path.The
GeoIP2class now supports.mmdbfiles downloaded from DB-IP.The OpenLayers template widget no longer includes inline CSS (which also removes the former
map_cssblock) to better comply with a strict Content Security Policy.OpenLayersWidgetis now based on OpenLayers 7.2.2 (previously 4.6.5).The new
isemptylookup andIsEmpty()expression allow filtering empty geometries on PostGIS.The new
FromWKB()andFromWKT()functions allow creating geometries from Well-known binary (WKB) and Well-known text (WKT) representations.
django.contrib.postgresLien vers cette rubrique
The new
trigram_strict_word_similarlookup, and theTrigramStrictWordSimilarity()andTrigramStrictWordDistance()expressions allow using trigram strict word similarity.The
arrayfield.overlaplookup now supportsQuerySet.values()andvalues_list()as a right-hand side.
django.contrib.sitemapsLien vers cette rubrique
The new
Sitemap.get_languages_for_item()method allows customizing the list of languages for which the item is displayed.
django.contrib.staticfilesLien vers cette rubrique
ManifestStaticFilesStoragenow has experimental support for replacing paths to JavaScript modules inimportandexportstatements with their hashed counterparts. If you want to try it, subclassManifestStaticFilesStorageand set thesupport_js_module_import_aggregationattribute toTrue.The new
ManifestStaticFilesStorage.manifest_hashattribute provides a hash over all files in the manifest and changes whenever one of the files changes.
Moteurs de base de donnéesLien vers cette rubrique
The new
"assume_role"option is now supported inOPTIONSon PostgreSQL to allow specifying the session role.The new
"server_side_binding"option is now supported inOPTIONSon PostgreSQL withpsycopg3.1.8+ to allow using server-side binding cursors.
Signalement d’erreursLien vers cette rubrique
The debug page now shows exception notes and fine-grained error locations on Python 3.11+.
Session cookies are now treated as credentials and therefore hidden and replaced with stars (
**********) in error reports.
FormulairesLien vers cette rubrique
ModelFormnow accepts the newMetaoptionformfield_callbackto customize form fields.modelform_factory()now respects theformfield_callbackattribute of theform’sMeta.
InternationalisationLien vers cette rubrique
Added support and translations for the Central Kurdish (Sorani) language.
JournalisationLien vers cette rubrique
The django.db.backends logger now logs transaction management queries (
BEGIN,COMMIT, andROLLBACK) at theDEBUGlevel.
Commandes d’administrationLien vers cette rubrique
makemessagescommand now supports locales with private sub-tags such asnl_NL-x-informal.The new
makemigrations --updateoption merges model changes into the latest migration and optimizes the resulting operations.
MigrationsLien vers cette rubrique
Migrations now support serialization of
enum.Flagobjects.
ModèlesLien vers cette rubrique
QuerySetnow extensively supports filtering against Fonctions de fenêtrage with the exception of disjunctive filter lookups against window functions when performing aggregation.prefetch_related()now supportsPrefetchobjects with sliced querysets.Registering lookups on
Fieldinstances is now supported.The new
robustargument foron_commit()allows performing actions that can fail after a database transaction is successfully committed.The new
KT()expression represents the text value of a key, index, or path transform ofJSONField.Nownow supports microsecond precision on MySQL and millisecond precision on SQLite.F()expressions that outputBooleanFieldcan now be negated using~F()(inversion operator).Modelnow provides asynchronous versions of some methods that use the database, using anaprefix:adelete(),arefresh_from_db(), andasave().Related managers now provide asynchronous versions of methods that change a set of related objects, using an
aprefix:aadd(),aclear(),aremove(), andaset().CharField.max_lengthis no longer required to be set on PostgreSQL, which supports unlimitedVARCHARcolumns.
Requêtes et réponsesLien vers cette rubrique
StreamingHttpResponsenow supports async iterators when Django is served via ASGI.
TestsLien vers cette rubrique
The
test --debug-sqloption now formats SQL queries withsqlparse.The
RequestFactory,AsyncRequestFactory,Client, andAsyncClientclasses now support theheadersparameter, which accepts a dictionary of header names and values. This allows a more natural syntax for declaring headers.# Before: self.client.get("/home/", HTTP_ACCEPT_LANGUAGE="fr") await self.async_client.get("/home/", ACCEPT_LANGUAGE="fr") # After: self.client.get("/home/", headers={"accept-language": "fr"}) await self.async_client.get("/home/", headers={"accept-language": "fr"})
UtilitairesLien vers cette rubrique
The new
encoderparameter fordjango.utils.html.json_script()function allows customizing a JSON encoder class.The private internal vendored copy of
urllib.parse.urlsplit()now strips'\r','\n', and'\t'(see CVE 2022-0391 and bpo-43882). This is to protect projects that may be incorrectly using the internalurl_has_allowed_host_and_scheme()function, instead of using one of the documented functions for handling URL redirects. The Django functions were not affected.The new
django.utils.http.content_disposition_header()function returns aContent-DispositionHTTP header value as specified by RFC 6266.
ValidateursLien vers cette rubrique
The list of common passwords used by
CommonPasswordValidatoris updated to the most recent version.
Backwards incompatible changes in 4.2Lien vers cette rubrique
API de moteur de base de donnéesLien vers cette rubrique
Cette section décrit des modifications qui pourraient être nécessaires dans des moteurs de base de données tiers.
DatabaseFeatures.allows_group_by_pkis removed as it only remained to accommodate a MySQL extension that has been supplanted by proper functional dependency detection in MySQL 5.7.15. Note thatDatabaseFeatures.allows_group_by_selected_pksis still supported and should be enabled if your backend supports functional dependency detection inGROUP BYclauses as specified by theSQL:1999standard.inspectdbnow usesdisplay_sizefromDatabaseIntrospection.get_table_description()rather thaninternal_sizeforCharField.
Dropped support for MariaDB 10.3Lien vers cette rubrique
Upstream support for MariaDB 10.3 ends in May 2023. Django 4.2 supports MariaDB 10.4 and higher.
Dropped support for MySQL 5.7Lien vers cette rubrique
Upstream support for MySQL 5.7 ends in October 2023. Django 4.2 supports MySQL 8 and higher.
Dropped support for PostgreSQL 11Lien vers cette rubrique
Upstream support for PostgreSQL 11 ends in November 2023. Django 4.2 supports PostgreSQL 12 and higher.
Setting update_fields in Model.save() may now be requiredLien vers cette rubrique
In order to avoid updating unnecessary columns,
QuerySet.update_or_create() now passes update_fields to the
Model.save() calls. As a consequence, any
fields modified in the custom save() methods should be added to the
update_fields keyword argument before calling super(). See
Surcharge des méthodes de modèles prédéfinies for more details.
Dropped support for raw aggregations on MySQLLien vers cette rubrique
MySQL 8+ allows functional dependencies on GROUP BY columns, so the
pre-Django 4.2 workaround of grouping by primary keys of the main table is
removed. As a consequence, using RawSQL() aggregations is no longer
supported on MySQL as there is no way to determine if such aggregations are
needed or valid in the GROUP BY clause. Use Fonctions d’agrégation
instead.
DiversLien vers cette rubrique
The undocumented
django.http.multipartparser.parse_header()function is removed. Usedjango.utils.http.parse_header_parameters()instead.{% blocktranslate asvar … %}result is now marked as safe for (HTML) output purposes.The
autofocusHTML attribute in the admin search box is removed as it can be confusing for screen readers.The
makemigrations --checkoption no longer creates missing migration files.The
aliasargument forExpression.get_group_by_cols()is removed.The minimum supported version of
sqlparseis increased from 0.2.2 to 0.3.1.The undocumented
negatedparameter of theExistsexpression is removed.The
is_summaryargument of the undocumentedQuery.add_annotation()method is removed.The minimum supported version of SQLite is increased from 3.9.0 to 3.21.0.
The minimum supported version of
asgirefis increased from 3.5.2 to 3.6.0.UserCreationFormnow rejects usernames that differ only in case. If you need the previous behavior, useBaseUserCreationForminstead.The minimum supported version of
mysqlclientis increased from 1.4.0 to 1.4.3.The minimum supported version of
argon2-cffiis increased from 19.1.0 to 19.2.0.The minimum supported version of
Pillowis increased from 6.2.0 to 6.2.1.The minimum supported version of
jinja2is increased from 2.9.2 to 2.11.0.The minimum supported version of redis-py is increased from 3.0.0 to 3.4.0.
Manually instantiated
WSGIRequestobjects must be provided a file-like object forwsgi.input. Previously, Django was more lax than the expected behavior as specified by the WSGI specification.Support for
PROJ< 5 is removed.EmailBackendnow verifies ahostnameandcertificates. If you need the previous behavior that is less restrictive and not recommended, subclassEmailBackendand override thessl_contextproperty.
Fonctionnalités rendues obsolètes dans Django 4.2Lien vers cette rubrique
L’option index_together a été rendue obsolète en faveur de indexesLien vers cette rubrique
L’option Meta.index_together a été rendue obsolète en faveur de l’option indexes.
Migrating existing index_together should be handled as a migration. For
example:
class Author(models.Model):
rank = models.IntegerField()
name = models.CharField(max_length=30)
class Meta:
index_together = [["rank", "name"]]
Devrait devenir :
class Author(models.Model):
rank = models.IntegerField()
name = models.CharField(max_length=30)
class Meta:
indexes = [models.Index(fields=["rank", "name"])]
Running the makemigrations command will generate a migration
containing a RenameIndex operation
which will rename the existing index. Next, consider squashing migrations to
remove index_together from historical migrations.
The AlterIndexTogether migration operation is now officially supported only
for pre-Django 4.2 migration files. For backward compatibility reasons, it’s
still part of the public API, and there’s no plan to deprecate or remove it,
but it should not be used for new migrations. Use
AddIndex and
RemoveIndex operations instead.
Passing encoded JSON string literals to JSONField is deprecatedLien vers cette rubrique
JSONField and its associated lookups and aggregates used to allow passing
JSON encoded string literals which caused ambiguity on whether string literals
were already encoded from database backend’s perspective.
During the deprecation period string literals will be attempted to be JSON decoded and a warning will be emitted on success that points at passing non-encoded forms instead.
Code that used to pass JSON encoded string literals:
Document.objects.bulk_create(
Document(data=Value("null")),
Document(data=Value("[]")),
Document(data=Value('"foo-bar"')),
)
Document.objects.annotate(
JSONBAgg("field", default=Value("[]")),
)
Devrait devenir :
Document.objects.bulk_create(
Document(data=Value(None, JSONField())),
Document(data=[]),
Document(data="foo-bar"),
)
Document.objects.annotate(
JSONBAgg("field", default=[]),
)
From Django 5.1+ string literals will be implicitly interpreted as JSON string literals.
DiversLien vers cette rubrique
The
BaseUserManager.make_random_password()method is deprecated. See recipes and best practices for using Python’ssecretsmodule to generate passwords.The
length_istemplate filter is deprecated in favor oflengthand the==operator within an{% if %}tag. For example{% if value|length == 4 %}…{% endif %} {% if value|length == 4 %}True{% else %}False{% endif %}instead of:
{% if value|length_is:4 %}…{% endif %} {{ value|length_is:4 }}django.contrib.auth.hashers.SHA1PasswordHasher,django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher, anddjango.contrib.auth.hashers.UnsaltedMD5PasswordHasherare deprecated.django.contrib.postgres.fields.CICharFieldis deprecated in favor ofCharField(db_collation="…")with a case-insensitive non-deterministic collation.django.contrib.postgres.fields.CIEmailFieldis deprecated in favor ofEmailField(db_collation="…")with a case-insensitive non-deterministic collation.django.contrib.postgres.fields.CITextFieldis deprecated in favor ofTextField(db_collation="…")with a case-insensitive non-deterministic collation.django.contrib.postgres.fields.CITextmixin is deprecated.The
map_heightandmap_widthattributes ofBaseGeometryWidgetare deprecated, use CSS to size map widgets instead.SimpleTestCase.assertFormsetError()is deprecated in favor ofassertFormSetError().TransactionTestCase.assertQuerysetEqual()is deprecated in favor ofassertQuerySetEqual().Passing positional arguments to
SignerandTimestampSigneris deprecated in favor of keyword-only arguments.The
DEFAULT_FILE_STORAGEsetting is deprecated in favor ofSTORAGES["default"].The
STATICFILES_STORAGEsetting is deprecated in favor ofSTORAGES["staticfiles"].La fonction
django.core.files.storage.get_storage_class()est obsolète.
Comments on columns and tablesLien vers cette rubrique#
The new
Field.db_commentandMeta.db_table_commentoptions allow creating comments on columns and tables, respectively. For example:Also, the new
AlterModelTableCommentoperation allows changing table comments defined in theMeta.db_table_comment.