メインコンテンツにスキップ

Django 6.0の新機能まとめ|Celery不要のタスク実行・CSP・テンプレートパーシャル

Django 6.0の新機能まとめ|Celery不要のタスク実行・CSP・テンプレートパーシャル

2026/02/15に公開

「ちょっとしたメール送信を非同期にしたいだけなのに、Celeryを入れるのは大げさだな...」と感じたことはありませんか?

2025年12月3日にリリースされたDjango 6.0で、ついにその悩みが解決されました。Celery不要のバックグラウンドタスク組み込みCSPサポートなど、ずっと欲しかった機能が揃ったリリースです。

僕もさっそく試してみましたが、特にバックグラウンドタスクは「これを待ってた!」という感動ものでした。この記事では、Django 6.0の主要な新機能をコード例付きで解説していきます。破壊的変更についてもまとめたので、アップグレードの参考にしてください。

Note

対象読者:

  • Django 5.x以前を使っている開発者
  • Django 6.0へのアップグレードを検討中の方
  • Djangoの最新動向をキャッチアップしたい方

4大新機能

Django 6.0の目玉は、次の4つの新機能です。

バックグラウンドタスク

これまでDjangoでバックグラウンド処理をするには、CeleryやDjango Q2といったサードパーティライブラリが必須でした。Django 6.0からは組み込みのTasksフレームワークが使えます。

タスクの定義は@taskデコレータを付けるだけです。

tasks.py
from django.core.mail import send_mail from django.tasks import task @task def send_welcome_email(user_email, username): send_mail( subject="ようこそ!", message=f"{username}さん、登録ありがとうございます!", from_email=None, recipient_list=[user_email], )

タスクの実行も直感的です。enqueue()を呼ぶだけでキューに追加されます。

views.py
from .tasks import send_welcome_email def register(request): # ユーザー登録処理... send_welcome_email.enqueue( user_email=user.email, username=user.username, ) return redirect("home")

バックエンドの設定

Tasksフレームワークには2つの組み込みバックエンドがあります。

バックエンド用途特徴
ImmediateBackend開発用タスクを同期的に即実行
DummyBackendテスト用タスクを記録するだけ

本番環境では、django-tasksパッケージのDatabaseBackendがおすすめです。SQLデータベースにタスクを保存するので、Redisなどの追加インフラが不要です。

settings.py
INSTALLED_APPS = [ "django_tasks", "django_tasks.backends.database", ] TASKS = { "default": { "BACKEND": "django_tasks.backends.database.DatabaseBackend", }, }
Tip

DatabaseBackendはデータベーストランザクション内でタスクをアトミックにキューイングできます。「ユーザー作成が成功したらメール送信」のようなケースで安心です。

CSPサポート

Content Security Policy(CSP) は、XSSなどのインジェクション攻撃を防ぐブラウザのセキュリティ機能です。これまではdjango-cspパッケージが必要でしたが、Django 6.0で標準装備になりました。

ミドルウェアを追加して、ポリシーを設定するだけで使えます。

settings.py
MIDDLEWARE = [ "django.middleware.csp.ContentSecurityPolicyMiddleware", # ... ]
settings.py
from django.utils.csp import CSP SECURE_CSP = { "default-src": [CSP.SELF], "script-src": [CSP.SELF, CSP.NONCE], "img-src": [CSP.SELF, "https:"], }

この設定で、以下のようなCSPヘッダーが自動生成されます。

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-ランダム値'; img-src 'self' https:

テンプレートではノンスを{{ csp_nonce }}で埋め込めます。

template.html
<script src="{% static 'app.js' %}" nonce="{{ csp_nonce }}"></script>
Tip

まずはSECURE_CSP_REPORT_ONLYで監視モードから始めるのがおすすめです。既存サイトへの影響を確認してから、SECURE_CSPで強制モードに切り替えましょう。

テンプレートパーシャル

テンプレートの再利用に、もう別ファイルを作る必要はありません。{% partialdef %}で部分テンプレートを定義し、{% partial %}で呼び出せます。

product_list.html
{# パーシャルを定義(inlineで定義箇所にもレンダリング) #} {% partialdef product_card inline %} <div class="card"> <h3>{{ product.name }}</h3> <p>{{ product.price }}</p> </div> {% endpartialdef %} {# 別の場所で同じパーシャルを再利用 #} <div class="featured"> {% partial product_card %} </div>

inlineを省略すると、定義箇所ではレンダリングされません。

テンプレート外からの参照も可能です。テンプレート名#パーシャル名の形式で、{% include %}render()から呼び出せます。

{% include "product_list.html#product_card" %}
Note

この機能はサードパーティのdjango-template-partialsパッケージが元になっています。htmxでのフラグメントレンダリングに特に相性が良いです。

モダンメールAPI

DjangoのメールシステムがPython 3.6+のemail.message.EmailMessageクラスに移行しました。基本的な使い方は変わりませんが、内部実装がモダンになっています。

from django.core.mail import EmailMessage email = EmailMessage( subject="お知らせ", body="新機能がリリースされました!", from_email="info@example.com", to=["user@example.com"], ) email.send()

MIMEPartを使ったインライン添付がよりシンプルになりました。

from email.message import MIMEPart inline_image = MIMEPart() inline_image.set_content( image_data, maintype="image", subtype="jpeg", disposition="inline", cid=cid, ) message.attach(inline_image)

また、send_mail()などの関数で、位置引数が非推奨になりました。

# 非推奨(位置引数) send_mail("件名", "本文", "from@example.com", ["to@example.com"], True) # 推奨(キーワード引数) send_mail( subject="件名", body="本文", from_email="from@example.com", recipient_list=["to@example.com"], fail_silently=True, )
Warning

SafeMIMETextSafeMIMEMultipartは非推奨になっています。これらを直接使っているコードは修正が必要です。

その他の注目改善

4大機能以外にも、開発が楽になる改善がたくさんあります。

save()後のフィールド自動リフレッシュ

これは地味ですが嬉しい改善です。GeneratedFieldやデータベースデフォルト値を持つフィールドが、save()後に自動で最新値に更新されます。もうrefresh_from_db()を手動で呼ぶ必要はありません。

from django.db import models from django.db.models.functions import Now class Article(models.Model): created_at = models.DateTimeField(db_default=Now()) # save()後すぐに値が使える article = Article() article.save() print(article.created_at) # 値がセットされている!

PostgreSQL、SQLite、OracleではSQLRETURNING句を活用して追加クエリなしで値を取得します。MySQL/MariaDBでは遅延読み込みで対応します。

Note

この機能は2016年からの機能リクエストがついに実現したものです。9年越しの改善です。

shell自動インポート拡張

manage.py shellでよく使うユーティリティが自動インポートされるようになりました。Django 5.2で追加されたモデルの自動インポートに加え、以下が使えます。

# すべて自動で利用可能 settings.DEBUG connection.queries functions.Lower("title") timezone.now()

デバッグや検証が手軽になって、日々のちょっとした確認が楽になります。

StringAgg汎用化

PostgreSQL限定だったStringAggが全データベースで使えるようになりました。

from django.db.models import StringAgg, Value # PostgreSQL以外でも動作する articles = Article.objects.annotate( tag_list=StringAgg("tags__name", delimiter=Value(", ")), )

インポート先がdjango.contrib.postgresからdjango.db.modelsに変わっています。

forloop.length

テンプレートのforループで、要素の総数を取得できるようになりました。

{% for article in articles %} <p>{{ forloop.counter }}/{{ forloop.length }}: {{ article.title }}</p> {% endfor %}

これまでは{{ articles|length }}を別途使う必要がありましたが、forloop変数から直接アクセスできます。

AsyncPaginator

非同期対応のページネーターが追加されました。ASGIアプリケーションでsync_to_asyncでラップする必要がなくなります。

from django.core.paginator import AsyncPaginator paginator = AsyncPaginator(queryset, per_page=25) page = await paginator.aget_page(page_number)

BigAutoFieldデフォルト化

DEFAULT_AUTO_FIELDのデフォルト値がAutoField(32bit)からBigAutoField(64bit)に変わりました。新規プロジェクトでは設定不要です。

AutoFieldの上限は約21億件です。大規模アプリケーションでは主キーが枯渇するリスクがありました。BigAutoFieldなら約922京件まで対応できるので、実質的に心配不要です。

Warning

既存プロジェクトでマイグレーションの影響を避けたい場合は、明示的に設定を追加してください。

DEFAULT_AUTO_FIELD = "django.db.models.AutoField"

破壊的変更

Django 6.0にアップグレードする前に、以下の変更点を確認しておきましょう。

Python・データベースのサポート変更

項目変更内容
Python3.10, 3.11のサポート終了。3.12以上が必要
MariaDB10.5のサポート終了。10.6以上が必要

DEFAULT_AUTO_FIELD

デフォルトがAutoFieldからBigAutoFieldに変わります。既存プロジェクトでは意図しないマイグレーションが生成される場合があります。settings.pyに明示的な設定を追加すれば回避できます。

カスタムORM式のas_sql()

カスタムORM式を定義している場合、as_sql()の戻り値のparamsがtuple必須になりました。

# Django 5.x def as_sql(self, compiler, connection): return sql, [param1, param2] # listでもOKだった # Django 6.0 def as_sql(self, compiler, connection): return sql, (param1, param2) # tupleが必須

メールAPI

SafeMIMETextSafeMIMEMultipartが非推奨になりました。BadHeaderErrorValueErrorに置き換えです。メール関連でカスタムサブクラスを使っている場合は確認してください。

まとめ

Django 6.0は、開発の快適さとセキュリティの両方が大きく改善されたリリースです。

個人的に一番嬉しいのは、やはりバックグラウンドタスクです。「メール送信を非同期にしたいだけなのにCeleryを入れるのか...」と悩んだ経験がある方は多いはず。軽量なタスク処理なら、Django標準の仕組みで十分対応できるようになりました。

アップグレードの際は、PythonバージョンとDEFAULT_AUTO_FIELDの変更に注意してください。django-upgradeツールを使えば、コードの自動修正もできます。

主な変更のおさらい:

  • バックグラウンドタスク: @taskデコレータ + enqueue()で手軽に非同期処理
  • CSPサポート: ミドルウェア追加と設定だけでXSS対策を強化
  • テンプレートパーシャル: {% partialdef %}で部分テンプレートを定義・再利用
  • モダンメールAPI: 内部がPython標準のEmailMessageに移行
  • その他: save()自動リフレッシュ、StringAgg汎用化、AsyncPaginator等
Tip

Django 5.2はLTS(Long Term Support)です。すぐにアップグレードする必要はありません。まずはテスト環境で動作確認してから、本番への適用を検討しましょう。

参考リンク

共有
Xにポスト
Facebookに投稿
はてなブックマークに登録
LINEで共有
リンクをコピー

この記事はいかがでしたか?

もしこの記事が参考になりましたら、
高評価をいただけると大変嬉しいです!

皆様からの応援が励みになります。ありがとうございます! ✨

techarm

エンジニア歴10年以上。Rust / Go / React / Python を中心にWeb開発しています。
日々の学びや技術的な知見をこのブログで発信しています。