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
でpsycopg
3.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-Disposition
HTTPヘッダー値を返します。
バリデータ¶
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 の検索ボックスで
autofocus
HTML 属性が削除されました。これはスクリーンリーダーにとって混乱を招く可能性があるためです。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 のサポートが削除されました。EmailBackend
はhostname
とcertificates
を検証するようになりました。より制限の少ない、非推奨の以前の動作が必要な場合は、EmailBackend
をサブクラスにしてssl_context
プロパティをオーバーライドしてください。
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 文字列リテラルとして暗黙的に解釈されるようになります。
その他¶
BaseUserManager.make_random_password()
メソッドは非推奨です。パスワードを生成するために Python のsecrets
モジュールを使用する際のレシピとベストプラクティスについては 、レシピとベストプラクティス を参照してください。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()
関数は非推奨となりました。