Django 6.0の新機能まとめ|Celery不要のタスク実行・CSP・テンプレートパーシャル
「ちょっとしたメール送信を非同期にしたいだけなのに、Celeryを入れるのは大げさだな...」と感じたことはありませんか?
2025年12月3日にリリースされたDjango 6.0で、ついにその悩みが解決されました。Celery不要のバックグラウンドタスクや組み込みCSPサポートなど、ずっと欲しかった機能が揃ったリリースです。
僕もさっそく試してみましたが、特にバックグラウンドタスクは「これを待ってた!」という感動ものでした。この記事では、Django 6.0の主要な新機能をコード例付きで解説していきます。破壊的変更についてもまとめたので、アップグレードの参考にしてください。
対象読者:
- Django 5.x以前を使っている開発者
- Django 6.0へのアップグレードを検討中の方
- Djangoの最新動向をキャッチアップしたい方
4大新機能
Django 6.0の目玉は、次の4つの新機能です。
▶バックグラウンドタスク
これまでDjangoでバックグラウンド処理をするには、CeleryやDjango Q2といったサードパーティライブラリが必須でした。Django 6.0からは組み込みのTasksフレームワークが使えます。
タスクの定義は@taskデコレータを付けるだけです。
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()を呼ぶだけでキューに追加されます。
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などの追加インフラが不要です。
INSTALLED_APPS = [
"django_tasks",
"django_tasks.backends.database",
]
TASKS = {
"default": {
"BACKEND": "django_tasks.backends.database.DatabaseBackend",
},
}DatabaseBackendはデータベーストランザクション内でタスクをアトミックにキューイングできます。「ユーザー作成が成功したらメール送信」のようなケースで安心です。
▶CSPサポート
Content Security Policy(CSP) は、XSSなどのインジェクション攻撃を防ぐブラウザのセキュリティ機能です。これまではdjango-cspパッケージが必要でしたが、Django 6.0で標準装備になりました。
ミドルウェアを追加して、ポリシーを設定するだけで使えます。
MIDDLEWARE = [
"django.middleware.csp.ContentSecurityPolicyMiddleware",
# ...
]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 }}で埋め込めます。
<script src="{% static 'app.js' %}" nonce="{{ csp_nonce }}"></script>まずはSECURE_CSP_REPORT_ONLYで監視モードから始めるのがおすすめです。既存サイトへの影響を確認してから、SECURE_CSPで強制モードに切り替えましょう。
▶テンプレートパーシャル
テンプレートの再利用に、もう別ファイルを作る必要はありません。{% partialdef %}で部分テンプレートを定義し、{% partial %}で呼び出せます。
{# パーシャルを定義(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" %}この機能はサードパーティの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,
)SafeMIMETextとSafeMIMEMultipartは非推奨になっています。これらを直接使っているコードは修正が必要です。
その他の注目改善
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では遅延読み込みで対応します。
この機能は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京件まで対応できるので、実質的に心配不要です。
既存プロジェクトでマイグレーションの影響を避けたい場合は、明示的に設定を追加してください。
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"破壊的変更
Django 6.0にアップグレードする前に、以下の変更点を確認しておきましょう。
▶Python・データベースのサポート変更
| 項目 | 変更内容 |
|---|---|
| Python | 3.10, 3.11のサポート終了。3.12以上が必要 |
| MariaDB | 10.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
SafeMIMETextとSafeMIMEMultipartが非推奨になりました。BadHeaderErrorもValueErrorに置き換えです。メール関連でカスタムサブクラスを使っている場合は確認してください。
まとめ
Django 6.0は、開発の快適さとセキュリティの両方が大きく改善されたリリースです。
個人的に一番嬉しいのは、やはりバックグラウンドタスクです。「メール送信を非同期にしたいだけなのにCeleryを入れるのか...」と悩んだ経験がある方は多いはず。軽量なタスク処理なら、Django標準の仕組みで十分対応できるようになりました。
アップグレードの際は、PythonバージョンとDEFAULT_AUTO_FIELDの変更に注意してください。django-upgradeツールを使えば、コードの自動修正もできます。
主な変更のおさらい:
- バックグラウンドタスク:
@taskデコレータ +enqueue()で手軽に非同期処理 - CSPサポート: ミドルウェア追加と設定だけでXSS対策を強化
- テンプレートパーシャル:
{% partialdef %}で部分テンプレートを定義・再利用 - モダンメールAPI: 内部がPython標準のEmailMessageに移行
- その他: save()自動リフレッシュ、StringAgg汎用化、AsyncPaginator等
Django 5.2はLTS(Long Term Support)です。すぐにアップグレードする必要はありません。まずはテスト環境で動作確認してから、本番への適用を検討しましょう。
▶参考リンク
この記事はいかがでしたか?
もしこの記事が参考になりましたら、
高評価をいただけると大変嬉しいです!
皆様からの応援が励みになります。ありがとうございます! ✨