2022年8月3日、Django 4.1がリリースされました。
公式サイトでのリリース情報は以下を参照してください。
Django 4.1 release notes | Django documentation | Django
4.1のサポート期限は2023年12月です。3.2 LTSからアップデートするとサポート期限が短くなってしまうことに注意してください(3.2 LTSのサポート期限は2024年4月)。 サポート期限を短くしたくない場合は、2023年4月リリース予定の4.2 LTSまでアップデートしない手もあります(4.2 LTSのサポート期限は2026年4月)。 各バージョンのサポート期限についての詳細は以下公式ドキュメント「Supported Versions」を参照してください。
それでは、主な変更点について紹介します。
Asynchronous handlers for class-based views
ついに非同期クラスベースViewが書けるようになりました。Django 3.1では非同期関数ベースViewをサポートするようになりましたが、これで関数、クラス両方で非同期Viewを書けます。
非同期クラスベースViewの書き方は、メソッドの先頭にasync
を入れるだけです。
|
|
Asynchronous ORM interface
Model操作が非同期インタフェースを提供するようになりました。
create()
、get()
、delete()
などのメソッドの非同期用は、先頭にaを付けたメソッドacreate()
、aget()
、adelete()
です。
また、all()
、filter()
などを使ってfor文でデータを取り出したい場合は、for
の先頭にasync
を付けます。
同期処理用と非同期処理用で書き方が2通りできて難しくなったように感じるかもしれませんが、あまり頑張って覚えようとしなくても大丈夫です。
基本的には従来どおりの同期処理用の書き方を覚えておけば良くて、非同期処理で使えない場合はDjangoがSynchronousOnlyOperation
エラーを発生させて教えてくれます。
そうなった場合は、前述の「先頭にaを付けたメソッド」か「for
の先頭にasync
」のどちらかのパターンでエラーを回避できます。
以下で非同期処理でのModel操作の例を紹介します。
|
|
ただし、Model操作は非同期インタフェースを提供しているものの、4.1時点では裏側のデータベース接続は同期処理のままです。非同期処理の中で実行してもデータの損失、破損が発生しない安全な処理にはなっていますが、ボトルネックになる可能性はあります。
非同期でのデータベース接続は将来のバージョンでサポートされる予定です。
Validation of Constraints
ModelのMeta.constraintsに指定したデータベースへの制約をバリデーションで使えるようになりました。
実際の動作を確認するため、以下のModelをCreateViewで登録する画面を作ってみましょう。
|
|
Django 4.0の場合、age
に18未満を入力しようとすると、以下のようにIntegrityError
が発生します。
Django 4.1では以下のようにエラーメッセージが表示されます。
violation_error_messageを指定すればエラーメッセージのカスタマイズもできます。
前述の例のエラーメッセージを変更する場合は以下のようにします。
|
|
Form rendering accessibility
{{ form }}
でレンダリングされるフォームのテンプレートに、divタグベースの新しいものが追加されました。
スクリーンリーダーなどサイトの自動読み取りを行うツールでは、divタグを使ったサイトの方が読み取りやすいということで、追加されたようです。
ただし、divタグベースの出力はDjango 4.1時点で非デフォルトです。
divタグベースを使いたい場合は、FORM_RENDERERにdjango.forms.renderers.DjangoDivFormRendererまたはdjango.forms.renderers.Jinja2DivFormRendererを指定します。
ただし、django.forms.renderers.DjangoDivFormRenderer
、django.forms.renderers.Jinja2DivFormRenderer
はDjango 5.0で非推奨(Django 6.0で廃止予定)になるので注意してください。
Django 5.0からはdivタグベースの方がデフォルトになります。
では、実際の出力内容を見てみましょう。
まずは現在のデフォルトdjango.forms.renderers.DjangoTemplates
の出力内容です。(見やすくするためにスペースや改行を取り除いています)。
|
|
これは従来と同じ内容です。次に、新しく追加されたテンプレートクラスdjango.forms.renderers.DjangoDivFormRenderer
の出力内容です。
|
|
divタグで囲ったフォームが出力されました。
CSRF_COOKIE_MASKED setting
True
のときCookieをマスキングできる設定CSRF_COOKIE_MASKEDが追加されました。
新機能ですが、いきなり非推奨扱いになっています。Django 5.0で削除される予定です。
DjangoではもともとBREACH攻撃対策としてCookieをマスキングしていたのですが、対策として意味がないと判明したため、Django 4.1からはデフォルトでマスキングなしになりました。CSRF_COOKIE_MASKED
は下位互換性のために追加された機能です。基本的には使わないようにしましょう。
CSRF_COOKIE_MASKED
が実装されるまでの議論の過程は以下を参照してください。
#32800 (CsrfViewMiddleware unnecessarily masks CSRF cookie) – Django
Log out via GET
ログアウト機能を提供する汎用View django.contrib.auth.views.LogoutViewへのGETリクエストが非推奨となり、POSTリクエストを受けるけるようになりました。
GETリクエストでのログアウトはDjango 5.0で廃止される予定です。
POSTリクエストのログアウトボタンをリンク風UIにするには、CSSを使う必要があります。以下リリースノートの例が参考になります。
https://docs.djangoproject.com/en/4.1/releases/4.1/#log-out-via-get
上記の例を実装すると、ブラウザ上では以下のように表示されます。
この変更を採用するに至った議論は以下のチケットに載っているので、興味がある方は読んでみてください(なんと、クローズするまで10年以上かかっています…!)。