Django 4.2 リリースノート¶
2023年4月3日
Django 4.2 へようこそ!
このリリースノートでは、 バージョン 4.2 の新機能 と、Django 4.1 以前からアップグレードする際に注意すべき、 後方互換性のない変更 について説明します。また、 一部の機能を非推奨 としました。
既存のプロジェクトをアップデートするときは、 Django の新しいバージョンへの更新 ガイドに従ってください。
Django 4.2 は、長期サポートリリース として指定されています。リリースから最低3年間はセキュリティアップデートを受けます。以前の LTS である Django 3.2 に対するサポートは2024年4月に終了します。
Python バージョン間の互換性¶
Django 4.2 は、Python 3.8、3.9、3.10、3.11、および 3.12 (4.2.8 時点) をサポートしています。各シリーズの最新リリースのみが 強く推奨され 、公式にサポートされています。
Django 4.2 の新機能¶
Psycopg 3 のサポート¶
Django は psycopg バージョン 3.1.8 以降をサポートするようになりました。コードを更新するには、 psycopg ライブラリ をインストールしてください。 django.db.backends.postgresql は両方のライブラリをサポートしているので、 ENGINE を変更する必要はありません。
psycopg2 のサポートは、将来のある時点で非推奨となり削除される可能性があります。
psycopg 3 は psycopg2 と比較して、いくつかの変更点があることに注意してください。結果として、psycopg2 との違いを考慮した変更が必要になるかもしれません。
カラムとテーブルにおけるコメント¶
新しい Field.db_comment と Meta.db_table_comment オプションは、それぞれカラムとテーブルにコメントを作成できるようにします。例えば:
from django.db import models
class Question(models.Model):
text = models.TextField(db_comment="Poll question")
pub_date = models.DateTimeField(
db_comment="Date and time when the question was published",
)
class Meta:
db_table_comment = "Poll questions"
class Answer(models.Model):
question = models.ForeignKey(
Question,
on_delete=models.CASCADE,
db_comment="Reference to a question",
)
answer = models.TextField(db_comment="Question answer")
class Meta:
db_table_comment = "Question answers"
また、新しい AlterModelTableComment オペレーションにより、 Meta.db_table_comment で定義されたテーブルコメントを変更できるようになりました。
BREACH 攻撃に対する緩和策¶
GZipMiddleware に BREACH 攻撃の緩和機能が追加されました。BREACH 攻撃をより困難にするために、gzip レスポンスに最大 100 バイトのランダムバイトを追加します。この緩和手法については Heal The Breach (HTB) paper を参照してください。
インメモリファイルストレージ¶
新しい django.core.files.storage.InMemoryStorage クラスは、ディスクアクセスを回避してテストを高速化するのに便利な非永続的なストレージを提供します。
カスタムファイルストレージ¶
新しい STORAGES 設定では、複数のカスタムファイルストレージバックエンドを設定できます。また、 ファイル ("default" キー) と 静的ファイル ("staticfiles" キー) を管理するためのストレージエンジンを制御します。
古い DEFAULT_FILE_STORAGE と STATICFILES_STORAGE の設定はこのリリースで非推奨になりました。
マイナーな機能¶
django.contrib.admin¶
admin 画面のカラーテーマのライト/ダークは、システム設定に従うだけでなく、UIでも切り替えられるようになりました。
管理者のフォントスタックがシステムUIフォントを優先するようになり、フォントのダウンロードが不要になりました。さらに、CSS変数が利用可能になり、デフォルトのフォントファミリーをより簡単に上書きできるようになりました。
admin/delete_confirmation.html テンプレートに、カスタマイズを容易にするためのブロックとスクリプトフックが追加されました。
filter_horizontalとfilter_verticalウィジェットの選択オプションがフィルタ可能になりました。admin/base.htmlテンプレートに新しいブロックnav-breadcrumbsが追加され、ナビゲーションランドマークとbreadcrumbsブロックが含まれるようになりました。ModelAdmin.list_editableが編集時にアトミックトランザクションを使用するようになりました。jQuery のバージョンが 3.6.0 から 3.6.4 にアップグレードされました。
django.contrib.auth¶
PBKDF2 パスワードハッシュに対するデフォルトのイテレーション回数が 390,000 から 600,000 に増加しました。
UserCreationFormがカスタムユーザーモデルの多対多のフォームフィールドを保存するようになりました。新しい
BaseUserCreationFormがユーザ作成フォームをカスタマイズするための推奨基本クラスになりました。
django.contrib.gis¶
GeoJSON シリアライザ は、シリアライズされたフィーチャの
idキーを出力するようになりました。GDALRasterクラスがpathlib.Pathをサポートするようになりました。GeoIP2クラスが DB-IP からダウンロードした.mmdbファイルをサポートするようになりました。OpenLayers テンプレートウィジェットにはインライン CSS が含まれなくなりました(以前の
map_cssブロックも削除されました)。これは、厳格なコンテンツセキュリティポリシーに準拠するためです。OpenLayersWidgetは、以前の OpenLayers 4.6.5 から OpenLayers 7.2.2 に基づくようになりました。新しい
isemptyルックアップとIsEmpty()式により、PostGIS上で空のジオメトリをフィルタリングできるようになりました。新しい
FromWKB()およびFromWKT()関数により、Well-known binary(WKB)および Well-known text(WKT)表現からジオメトリを作成できるようになりました。
django.contrib.postgres¶
新しい
trigram_strict_word_similarルックアップと、TrigramStrictWordSimilarity()およびTrigramStrictWordDistance()式により、trigram (トリグラム) の厳密な単語類似性を使用できるようになりました。arrayfield.overlapルックアップは、右辺としてQuerySet.values()およびvalues_list()をサポートするようになりました。
django.contrib.sitemaps¶
新しい
Sitemap.get_languages_for_item()メソッドにより、アイテムが表示される言語のリストをカスタマイズできるようになりました。
django.contrib.staticfiles¶
ManifestStaticFilesStorageは、importおよびexport文内のJavaScriptモジュールへのパスを、それらがハッシュ化されたものに置き換える実験的なサポートを提供するようになりました。これを試したい場合は、ManifestStaticFilesStorageをサブクラス化し、support_js_module_import_aggregation属性をTrueに設定してください。新しい
ManifestStaticFilesStorage.manifest_hash属性は、マニフェスト内のすべてのファイルに対するハッシュを提供し、ファイルのいずれかが変更されるたびに変更されます。
データベースバックエンド¶
新しい
"assume_role"オプションが PostgreSQL のOPTIONSでサポートされるようになり、セッションロール を指定できるようになりました。新しい
"server_side_binding"オプションが PostgreSQL のOPTIONSでpsycopg3.1.8+ と共にサポートされるようになり、サーバーサイドバインディングカーソル が使用できるようになりました。
エラー報告¶
フォーム¶
ModelFormは、フォームフィールドをカスタマイズするための新しいMetaオプションformfield_callbackを受け入れるようになりました。modelform_factory()は、formのMetaのformfield_callback属性を尊重するようになりました。
国際化 (internationalization)¶
中央クルド語(ソラニー)のサポートと翻訳を追加しました。
ロギング¶
django.db.backends ロガーは、トランザクション管理クエリ(
BEGIN、COMMIT、およびROLLBACK)をDEBUGレベルでログに記録するようになりました。
管理コマンド¶
makemessagesコマンドは、nl_NL-x-informalのようなプライベートサブタグを含むロケールをサポートするようになりました。新しい
makemigrations --updateオプションは、モデルの変更を最新のマイグレーションにマージし、結果として得られる操作を最適化します。
マイグレーション¶
マイグレーションは、
enum.Flagオブジェクトのシリアライズをサポートするようになりました。
モデル¶
QuerySetは、集計を実行する際のウィンドウ関数に対する非結合フィルタールックアップを除き、ウィンドウ関数 に対するフィルタリングを広範囲にサポートするようになりました。prefetch_related()は、スライスされたクエリセットを持つPrefetchオブジェクトをサポートするようになりました。新しい
robust引数をon_commit()に指定することで、データベーストランザクションが成功した後に失敗する可能性のあるアクションを実行できるようになりました。新しい
KT() 式は、JSONFieldのキー、インデックス、またはパス・トランスフォームのテキスト値を表します。Nowは、MySQL上でマイクロ秒の精度、SQLite上でミリ秒の精度をサポートするようになりました。BooleanFieldを出力するF() 式は、~F()(反転演算子) を使用して否定できるようになりました。Modelは、データベースを使用するいくつかのメソッドの非同期バージョンをaプレフィックスを使用して提供するようになりました:adelete()、arefresh_from_db()、およびasave()。関係マネージャは、リレーション先オブジェクトのセットを変更するメソッドの非同期バージョンを
aプレフィックスを使用して提供するようになりました:aadd()、aclear()、aremove()、およびaset()。PostgreSQLでは無制限の
VARCHARカラムをサポートしているため、CharField.max_lengthを設定する必要がなくなりました。
Request と Response¶
DjangoがASGI経由で提供される場合、
StreamingHttpResponseは非同期イテレータをサポートするようになりました。
テスト¶
test --debug-sqlオプションは、SQLクエリをsqlparseでフォーマットするようになりました。RequestFactory、AsyncRequestFactory、Client、およびAsyncClientクラスは、ヘッダー名と値の辞書を受け入れる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"})
ユーティリティ¶
django.utils.html.json_script()関数の新しいencoderパラメータにより、JSONエンコーダークラスをカスタマイズできるようになりました。プライベートで内部的に提供される
urllib.parse.urlsplit()のコピーは、現在'\r','\n', および'\t'を削除するようになりました (CVE 2022-0391 および bpo-43882 を参照)。これは、URLリダイレクトを処理するためのドキュメント化された関数のいずれかを使用する代わりに、内部のurl_has_allowed_host_and_scheme()関数を誤って使用している可能性があるプロジェクトを保護するためです。Djangoの関数は影響を受けませんでした。新しい
django.utils.http.content_disposition_header()関数は、RFC 6266 に指定されているようにContent-DispositionHTTPヘッダー値を返します。
バリデータ¶
CommonPasswordValidatorによって使用されるよくあるパスワードのリストが、最新バージョンに更新されました。
4.2 における後方互換性のない変更¶
データベースバックエンド API¶
このセクションでは、サードパーティのデータベースバックエンドで必要になる可能性のある変更について説明します。
DatabaseFeatures.allows_group_by_pkは削除されました。これは、MySQL 5.7.15で適切な機能依存性の検出によって置き換えられたMySQLの拡張機能に対応するために残されていたものです。DatabaseFeatures.allows_group_by_selected_pksはまだサポートされており、バックエンドがSQL:1999標準で指定されているように、GROUP BY句での機能依存性の検出をサポートしている場合は有効にするべきです。inspectdbは、CharFieldに対してinternal_sizeの代わりにDatabaseIntrospection.get_table_description()からのdisplay_sizeを使用するようになりました。
MariaDB 10.3 のサポートを終了しました¶
MariaDB 10.3のアップストリームサポートは2023年5月に終了します。Django 4.2はMariaDB 10.4以降をサポートしています。
MySQL 5.7 のサポートを終了しました¶
MySQL 5.7 のアップストリームサポートは 2023年10月に終了します。 Django 4.2 は MySQL 8 以降をサポートします。
PostgreSQL 11 のサポートを終了しました¶
PostgreSQL 11 のアップストリーム サポートは 2023 年 11 月に終了します。Django 4.2 は PostgreSQL 12 以降をサポートします。
Model.save() で update_fields の設定が必要になる場合があります¶
不要なカラムを更新するのを避けるために、 QuerySet.update_or_create() は現在、 update_fields を Model.save() の呼び出しに渡します。その結果、カスタム save() メソッドで変更されたフィールドは、 super() を呼び出す前に update_fields キーワード引数に追加されるべきです。詳細については 定義済みのモデルメソッドをオーバーライドする を参照してください。
MySQL での生の集計処理のサポートを廃止¶
MySQL 8 以降では、GROUP BY 列に対する機能依存を許可しているため、メインテーブルの主キーによるグルーピングというDjango 4.2 以前の回避策は削除されました。結果として、GROUP BY 句でそのような集計が必要であるか、または有効であるかを判断する方法がないため、MySQL での RawSQL() 集計の使用はもはやサポートされていません。代わりに 集計(Aggregation)関数 を使用してください。
その他¶
ドキュメント化されていない
django.http.multipartparser.parse_header()関数は削除されました。代わりにdjango.utils.http.parse_header_parameters()を使用してください。{% blocktranslate asvar … %}の結果は 、(HTML) 出力用途で安全とマークされるようになりました。admin の検索ボックスで
autofocusHTML 属性が削除されました。これはスクリーンリーダーにとって混乱を招く可能性があるためです。makemigrations --checkオプションは欠損したマイグレーションファイルを作成しなくなりました。Expression.get_group_by_cols()のalias引数が削除されました。sqlparseの最小サポートバージョンが 0.2.2 から 0.3.1 に引き上げられました。Exists式のドキュメント化されていなかったnegatedパラメータが削除されました。ドキュメント化されていない
Query.add_annotation()メソッドのis_summary引数が削除されました。SQLite のサポート最小バージョンが 3.9.0 から 3.21.0 に引き上げられました。
asgirefのサポートされている最低バージョンが 3.5.2 から 3.6.0 に引き上げられました。UserCreationFormは、大文字と小文字の違いしかないユーザーネームを拒否するようになりました。以前の動作が必要な場合は、代わりにBaseUserCreationFormを使用してください。mysqlclientの最小サポートバージョンが 1.4.0 から 1.4.3 に引き上げられました。argon2-cffiの最小サポートバージョンが 19.1.0 から 19.2.0 に引き上げられました。Pillowの最小サポートバージョンが 6.2.0 から 6.2.1 に引き上げられました。jinja2の最小サポートバージョンが 2.9.2 から 2.11.0 に引き上げられました。redis-py の最低サポートバージョンが 3.0.0 から 3.4.0 に引き上げられました。
手動でインスタンス化された
WSGIRequestオブジェクトには、wsgi.inputのためのファイルライクオブジェクトを提供する必要があります。以前、DjangoはWSGI仕様で想定される挙動よりも寛容でした。PROJ< 5 のサポートが削除されました。EmailBackendnow verifies ahostnameandcertificates. If you need the previous behavior that is less restrictive and not recommended, subclassEmailBackendand override thessl_contextproperty.
4.2 で非推奨となった機能¶
index_together オプションは indexes を優先するため非推奨になりました。¶
The Meta.index_together option is deprecated in favor of the
indexes option.
既存の index_together のマイグレーションはマイグレーションとして扱うべきです。例えば:
class Author(models.Model):
rank = models.IntegerField()
name = models.CharField(max_length=30)
class Meta:
index_together = [["rank", "name"]]
これは以下のようにすべきです:
class Author(models.Model):
rank = models.IntegerField()
name = models.CharField(max_length=30)
class Meta:
indexes = [models.Index(fields=["rank", "name"])]
makemigrations コマンドを実行すると、既存のインデックスをリネームする RenameIndex 操作が含まれるマイグレーションが生成されます。次に、履歴マイグレーションから index_together を削除するために、マイグレーションをスカッシュすることを検討してください。
AlterIndexTogether マイグレーションオペレーションは、現在公式には Django 4.2 より前のマイグレーションファイルのためにのみサポートされています。後方互換性の理由から、まだ公開 API の一部であり、非推奨化または削除する計画はありませんが、新しいマイグレーションでの使用は避けるべきです。代わりに AddIndex と RemoveIndex オペレーションを使用してください。
JSONField に、エンコードされた JSON 文字列リテラルを渡すことは非推奨になりました¶
JSONField とそれに関連するルックアップや集計は JSON エンコード済みの文字列リテラルを渡すことを許可していましたが、これは文字列リテラルがデータベースバックエンドの観点から既にエンコードされているかどうかについての曖昧さを引き起こしていました。
非推奨期間中、文字列リテラルは JSON デコードされようと試みられ、成功した場合には非エンコード形式を渡すよう指摘する警告が発せられます。
JSONエンコードされた文字列リテラルを渡すために使われていたコード:
Document.objects.bulk_create(
Document(data=Value("null")),
Document(data=Value("[]")),
Document(data=Value('"foo-bar"')),
)
Document.objects.annotate(
JSONBAgg("field", default=Value("[]")),
)
これは以下のようにすべきです:
Document.objects.bulk_create(
Document(data=Value(None, JSONField())),
Document(data=[]),
Document(data="foo-bar"),
)
Document.objects.annotate(
JSONBAgg("field", default=[]),
)
Django 5.1 以降、文字列リテラルは JSON 文字列リテラルとして暗黙的に解釈されるようになります。
その他¶
The
BaseUserManager.make_random_password()method is deprecated. See recipes and best practices for using Python'ssecretsmodule to generate passwords.length_isテンプレートフィルターは、lengthと==演算子を{% if %}タグ内で使用する形式に置き換えられました。例えば{% if value|length == 4 %}…{% endif %} {% if value|length == 4 %}True{% else %}False{% endif %}
これは以下の表記に代わるものです:
{% if value|length_is:4 %}…{% endif %} {{ value|length_is:4 }}
django.contrib.auth.hashers.SHA1PasswordHasher,django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher, そしてdjango.contrib.auth.hashers.UnsaltedMD5PasswordHasherは非推奨になりました。django.contrib.postgres.fields.CICharFieldは、大文字小文字を区別しない非決定的照合順序 (collation) を使用したCharField(db_collation="…")に置き換えられ、非推奨となりました。django.contrib.postgres.fields.CIEmailFieldは、大文字小文字を区別しない非決定的照合順序 (collation) を使用したEmailField(db_collation="…")に置き換えられ、非推奨となりました。django.contrib.postgres.fields.CITextFieldは、大文字小文字を区別しない非決定的照合順序 (collation) を使用したTextField(db_collation="…")に置き換えられ、非推奨になりました。django.contrib.postgres.fields.CITextミックスインは非推奨になりました。BaseGeometryWidgetのmap_height属性とmap_width属性は非推奨となりました。代わりに CSS を使用してマップウィジェットのサイズを設定してください。SimpleTestCase.assertFormsetError()はassertFormSetError()を用いるため非推奨となりました。TransactionTestCase.assertQuerysetEqual()は非推奨となり、assertQuerySetEqual()が推奨されます。SignerおよびTimestampSignerへ位置引数を渡すことは、キーワード専用引数を使用する形式への変更が推奨となり、非推奨となりました。DEFAULT_FILE_STORAGE設定はSTORAGES["default"]に置き換えられ、非推奨になりました。STATICFILES_STORAGE設定は非推奨となり、代わりにSTORAGES["staticfiles"]が推奨されます。django.core.files.storage.get_storage_class()関数は非推奨となりました。