2023年4月3日、Django 4.2がリリースされました。

Django 4.2リリースを祝ってジャンゴ・ラインハルトが演奏しています(DreamStudioで作成)

Django 4.2リリースを祝ってジャンゴ・ラインハルトが演奏しています(DreamStudioで作成)

公式サイトでのリリース情報は以下を参照してください。

Django 4.2 release notes | Django documentation | Django

Django 4.2はlong-term support(LTS)版です。サポート期限は2026年4月です。 各バージョンのサポート期限についての詳細は以下公式ドキュメント「Supported Versions」を参照してください。

Download Django | Django

Psycopg 3 support

psycopg 3.1.8以上をサポートするようになりました。 ENGINEは従来どおりdjango.db.backends.postgresqlを使えます。

psycopg 3系はデータベースとの非同期通信をサポートします。 ただ、Django Model自体のデータベース通信は同期処理のままのようです。

また、2系と3系には仕様の違いがいくつかあります。生クエリを発行するアプリケーションの場合は、以下の違いを把握してコードを変更する必要があるかもしれません。

Differences from psycopg2 - psycopg 3.2.0.dev1 documentation

Comments on columns and tables

Field.db_commentとMeta.db_table_commentでカラムとテーブルにコメントを付けられるようになりました。

リリースノートのサンプルコードを使って実際に付けられるコメントを見てみましょう。 データベースはPostgreSQL 15.2を使います。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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"

テーブル定義の内容は以下のとおりです。

psqlでの\d+ example_question;(カラムのコメントを確認)の実行結果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
                                                                            Table "public.example_question"
  Column  |           Type           | Collation | Nullable |             Default              | Storage  | Compression | Stats target |                  Description
----------+--------------------------+-----------+----------+----------------------------------+----------+-------------+--------------+-----------------------------------------------
 id       | bigint                   |           | not null | generated by default as identity | plain    |             |              |
 text     | text                     |           | not null |                                  | extended |             |              | Poll question
 pub_date | timestamp with time zone |           | not null |                                  | plain    |             |              | Date and time when the question was published
Indexes:
    "example_question_pkey" PRIMARY KEY, btree (id)
Referenced by:
    TABLE "example_answer" CONSTRAINT "example_answer_question_id_4e8f5232_fk_example_question_id" FOREIGN KEY (question_id) REFERENCES example_question(id) DEFERRABLE INITIALLY DEFERRED

psqlでの\d+ example_answer;(カラムのコメントを確認)の実行結果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
                                                          Table "public.example_answer"
   Column    |  Type  | Collation | Nullable |             Default              | Storage  | Compression | Stats target |       Description
-------------+--------+-----------+----------+----------------------------------+----------+-------------+--------------+-------------------------
 id          | bigint |           | not null | generated by default as identity | plain    |             |              |
 answer      | text   |           | not null |                                  | extended |             |              | Question answer
 question_id | bigint |           | not null |                                  | plain    |             |              | Reference to a question
Indexes:
    "example_answer_pkey" PRIMARY KEY, btree (id)
    "example_answer_question_id_4e8f5232" btree (question_id)
Foreign-key constraints:
    "example_answer_question_id_4e8f5232_fk_example_question_id" FOREIGN KEY (question_id) REFERENCES example_question(id) DEFERRABLE INITIALLY DEFERRED

psqlでのSELECT obj_description('example_question'::regclass);(テーブルのコメントを確認)の実行結果:

1
2
3
4
 obj_description
-----------------
 Poll questions
(1 row)

psqlでのSELECT obj_description('example_answer'::regclass);(テーブルのコメントを確認)の実行結果:

1
2
3
4
 obj_description
------------------
 Question answers
(1 row)

Mitigation for the BREACH attack

BREACH攻撃の緩和策のため、GZipMiddlewareはgzipレスポンスに最大100のランダムバイトを追加するようになりました。 この実装はHeal The Breach (HTB)という論文がベースになっています。

In-memory file storage

新しいストレージdjango.core.files.storage.InMemoryStorageが追加されました。ファイルをメモリ上に保存します。ディスクI/Oがなくなるのでテスト実行の高速化が期待できそうです。

Custom file storages

新しい設定項目STORAGESが追加されました。以下のように辞書型でエイリアス名とBACKENDをセットにして指定します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
STORAGES = {
    # ...
    "example1": {
        "BACKEND": "django.core.files.storage.FileSystemStorage",
        "OPTIONS": {
            "location": "/example",
            "base_url": "/example/",
        },
    },
    "example2": {
        "BACKEND": "django.core.files.storage.InMemoryStorage",
    },
}

ただし、以下のエイリアスは特別な意味を持ちます。

  • default
  • staticfiles
    • 静的ファイルを扱う際のデフォルトのストレージエンジン。STATICFILES_STORAGEと同じ役割

STORAGESに設定したエイリアスは以下のように呼び出せます。

1
2
3
4
5
>>> from django.core.files.storage import storages
>>> storages["example1"]
<django.core.files.storage.filesystem.FileSystemStorage object at 0x1072d1c10>
>>> storages["example2"]
<django.core.files.storage.memory.InMemoryStorage object at 0x1072d2150>

この変更に伴い、DEFAULT_FILE_STORAGESTATICFILES_STORAGEは非推奨になりました。