django-fastdevを使ってDjangoの開発体験を向上させよう
django-fastdev というPyPIパッケージが良かったので紹介します。
django-fastdev とは
パッケージの名前のとおり、Djangoの開発を手助けするライブラリです。
主に開発時のデバッグを楽にするための機能がいろいろあります。
使い方は INSTALLED_APPS に django_fastdev を追加するだけです(リンク元のREADMEを参照してください)。
ここでは代表的なdjango-fastdevの機能を紹介します
django-fastdevの機能
テンプレートで未定義の変数があれば例外を出す
Django Templateなどで未定義の変数を参照してしまうことがあります。通常であれば None として扱われるため変数の表示がないことに気付けないときもあります。
django-fastdevではそのような変数がテンプレートで呼び出されていた場合、 FastDevVariableDoesNotExist という例外が発出されます。
# templates/index.html などで views.py で参照していない no_variable_nameがある
...
{{ no_variable_name }}
...

なお、 default_if_none や default など、テンプレートの変数がNoneだった場合にフォールバックするテンプレートタグが呼び出されていれば(django-fastdevのデフォルトの設定では)例外はでません。
定義のないblock を呼び出した場合に例外を出す
Django Templateの変数と同様に {% block %} の呼び出し先が存在しない場合、通常であればエラーにはなりません。
django-fastdevを利用することで例外を発出します。
# templates/index.html などで存在しない no_block_nameを読んでしまう
...
{% block no_block_name %}
...

参照のないURLを呼び出したエラー画面に、存在する urlpattern 表示してくれる
{% url "no-url" %} など urls.py で定義したurlpatternsに存在しないURLを呼び出した場合、通常はReverse for 'no-url' not found. 'no-url' is not a valid view function or pattern name. といった例外だけが発出されます。
django-fastdevを利用していると、この情報に「定義済みのurlpatternsのリスト」を出してくれます

( These names exist: index と書いているのがわかります)
他にも紹介していない機能などがありますが、主に開発時のタイプミスに気づきやすくなるものがいくつかあります。
かゆいところに手が届く django-fastdev、一度試してみてください!
aspnet-codegeneratorを実行すると「You must install or update .NET to run this application.」が出たときの対処法
対象バージョン
.NET SDK 9.0.305, Mac OS X 13.7
ランタイム環境: OS Name: Mac OS X OS Version: 13.7 OS Platform: Darwin RID: osx-x64 Base Path: /Users/kimihito/.local/share/mise/installs/dotnet/9.0.305/sdk/9.0.305/
インストール済みの .NET ワークロード: 表示するインストール済みワークロードはありません。 新しいマニフェストをインストールするときに loose manifests を使用するように構成されています。
Host: Version: 9.0.9 Architecture: x64 Commit: 893c2ebbd4
.NET SDKs installed: 9.0.305 [/Users/kimihito/.local/share/mise/installs/dotnet/9.0.305/sdk]
.NET runtimes installed: Microsoft.AspNetCore.App 9.0.9 [/Users/kimihito/.local/share/mise/installs/dotnet/9.0.305/shared/Microsoft.AspNetCore.App] Microsoft.NETCore.App 9.0.9 [/Users/kimihito/.local/share/mise/installs/dotnet/9.0.305/shared/Microsoft.NETCore.App]
Other architectures found: None
Environment variables: DOTNET_ROOT [/Users/kimihito/.local/share/mise/installs/dotnet/9.0.305]
global.json file: Not found
Learn more: https://aka.ms/dotnet/info
Download .NET: https://aka.ms/dotnet/download
起こったこと
dotnet tool install dotnet-aspnet-codegenerator --global でインストール後に、dotnet aspnet-codegenerator を実行すると以下のエラーが出た
You must install or update .NET to run this application. App: /Users/kimihito/.dotnet/tools/dotnet-aspnet-codegenerator Architecture: x64 Framework: 'Microsoft.NETCore.App', version '8.0.0' (x64) .NET location: /Users/kimihito/.local/share/mise/installs/dotnet/9.0.305 The following frameworks were found: 9.0.9 at [/Users/kimihito/.local/share/mise/installs/dotnet/9.0.305/shared/Microsoft.NETCore.App]
.NET 9 を入れたはずなのに、.NET 8を要求されているよう。
解決法
dotnet tool install に --allow-roll-forward オプションを付与することで解決した。
具体的には
dotnet tool install dotnet-aspnet-codegenerator --allow-roll-forward --global とした
関連Issue
Django 6.0 に追加される機能からみる、Djangoのコア機能への考え方
Django 6.x Streering Council の一人である Carlton Gibsonさんが Django 6.0 への機能についてブログを書いていました
Looking forward to Django 6.0 • Buttondown
Django 6.0のアルファ版リリースは 2025-09-17 を予定しています
Django 6.0 に追加される機能
ブログ記事には以下の3点が記述されています
- CSP https://docs.djangoproject.com/en/dev/ref/csp/
- django-tasks (2025-09-03 時点で公式ドキュメントはなし)
- template-partials https://docs.djangoproject.com/en/dev/ref/templates/language/#template-partials
機能としてはそれぞれ別ですが、共通していることがあります。 それは「すべてサードパーティライブラリの機能をDjangoの機能として取り込んだ」ことです。(注: 同じインターフェースとは限らない)
- CSP https://github.com/mozilla/django-csp
- django-tasks https://github.com/RealOrangeOne/django-tasks
- template-partials https://github.com/carltongibson/django-template-partials
これらのパッケージはリリース済みのDjangoのバージョンでも利用ができます。
Djangoの「コア機能」とはなにか
先のブログ記事の作者である、CarltonさんはこのDjangoの「コア機能」への考えについて別の記事を書いています。
Thoughts on Django’s Core • Buttondown
概要として
機能が追加されるほど、メンテンス対象の範囲が増えてしまう
新しい機能はまずはサードパーティから始めよう
最後の2点は、Djangoの公式ドキュメントにも同様の記述があります。
Djangoの「変化」
Djangoについてよく耳にする批判の一つが「変化が遅い」「新しい機能が追加されない」というものです。確かに、他のWebフレームワークと比較すると、毎回のリリースで大きな新機能が追加されることは少ないかもしれません。
しかし、これは本当に「変化がない」ということなのでしょうか?Django 6.0の例を見ると、実際には3つもの重要な機能が追加されています。問題は「変化の見せ方」や「変化のアプローチ」が他のフレームワークと根本的に異なることなのです。
これまでCarltonさんのブログ記事の内容からみえるように、Djangoのコアに入ることはある種「枯れているか」を大切にしており、「変化」でなく「置き換え」とすることでDjangoの開発が進められていることがわかります。
まとめ
Django 6.0は「進化の仕方」を私たちに示しています。新しい機能を追加することと、実験的な機能を追加することは同じではありません。Djangoは常に進化していますが、その進化は慎重で、実証的で、長期的な視点に基づいています。 「変化がない」のではなく「変化の仕方が違う」のです。そして、この違いこそが、Djangoが20年にわたって多くの開発者に愛され続けている理由なのかもしれません。
余談ですが JavaScriptライブラリのhtmxにも似たような考えを表明した記事があり、こうした考え方への支持が一定数はあるのかもしれません。
ダラダラと書いてしまいましたが、Django 6.0のリリースが楽しみです!
Djangoの署名付きCookieをテストする方法
この記事のDjangoのバージョンは4.2になります。
署名付きCookieの設定
Djangoで署名付きCookieをセットする際は、set_signed_cookieメソッドを使用します。
from django.http import HttpResponse def my_view(request): response = HttpResponse("Hello, World!") response.set_signed_cookie('user_preference', 'dark_mode', salt='my_salt') return response
署名付きCookieのテスト方法
署名付きCookieが正しくセットされているかをテストしたい場合、django.core.signing.get_cookie_signerを使用することができます。
実際の値は django.core.signing.get_cookie_signer の返り値である django.core.signing.Signer の unsign メソッドを利用します。
テストコードの例
from django.test import TestCase, RequestFactory from django.core.signing import get_cookie_signer, BadSignature from myapp.views import my_view class SignedCookieTestCase(TestCase): def setUp(self): self.factory = RequestFactory() def test_signed_cookie_is_set_correctly(self): # ビューを呼び出してレスポンスを取得 request = self.factory.get('/') response = my_view(request) # Cookieが設定されているかを確認 self.assertIn('user_preference', response.cookies) # 署名付きCookieの値を検証 cookie_value = response.cookies['user_preference'].value signer = get_cookie_signer(salt='my_salt') # 署名を検証して元の値を取得 try: original_value = signer.unsign(cookie_value) self.assertEqual(original_value, 'dark_mode') except BadSignature: self.fail("Cookie signature is invalid")
重要なポイント
saltの指定は必須です。get_cookie_signerを使用する際は、set_signed_cookieで使用したのと同じsaltを指定してください。
# set_signed_cookieで使用したsaltと同じものを指定 signer = get_cookie_signer(salt='my_salt')
調べた理由
django.http.HttpRequest.get_signed_cookie をユニットテストで利用したかったのですが、うまく使うことができませんでした。
django.http.HttpRequest.get_signed_cookie のコードを見て、上記の実装方法があることを理解し、ユニットテストで利用しています。
まとめ
set_signed_cookieで署名付きCookieを設定- テスト時は
get_cookie_signerを使って署名を検証 - saltの指定を忘れずに
miseでPythonがインストールできない問題を解決した
小ネタです。
mise install python@3.12.11 を実行したところ以下のエラーが発生
mise ERROR git branch --show-current failed mise ERROR command ["git", "-C", "/Users/kimihito/Library/Caches/mise/python/pyenv", "-c", "safe.directory=/Users/kimihito/Library/Caches/mise/python/pyenv", "branch", "--show-current"] exited with code 128
「pyenvなんて使ってないけどなぁ」と思いつつmiseのIssueを検索。すると似たような問題に遭遇している人を発見。
ここのコメント にあったように
$ mise cache clear $ mise cache prune
を実行した後に再度 mise install python@3.12.11 を実行するとうまくいった。
uvのおかげでdjangoの関連パッケージにプルリクエストを送りやすくなった
最近はDjangoに新しいバージョンが出ると、その対応ができていることを示すプルリクエストを作成しています。高速なPythonパッケージマネージャであるuvを使うことで、このプロセスがとても簡単になりました。
2024年の例として、django-storages に Django 5.1 対応のプルリクエストを出すときに行った手順を紹介します。 https://github.com/jschneier/django-storages/pull/1444
やったこと
- リポジトリをforkする
uv venvを実行して仮想環境を作成(従来の方法より高速で依存関係の解決も正確です)- 仮想環境に入る
- django-storagesはtoxを使っている。手元にtoxがないので
pip install toxを実行する - Django 5.1をtoxのリストに追加するコミットを作る コミット内容
- プルリクエストを作成する プルリクエスト
- 失敗したこと: CHANGELOGファイルに記載するのを忘れてしまってました。別のプルリクエストを作りましたが、作者の方がご自身で対応してくれました。
Python歴が短い自分にとって、uvの高速な環境構築と依存関係の解決は大きな助けになっています。特に uv venv コマンド一つで清潔な環境が素早く作れるので、気軽にオープンソースへの貢献ができます。
Django自体の変化が少ないため、こうした対応をしなくても動くことが多い(実際django-storagesへのプルリクエストではパッケージ内のコードは変えていない)です。 ただ、明示的に対応バージョンを記載しておくことでユーザーにとってはメリットが大きいのかなと思っています。
注意点
こうした貢献は簡単ですが、同時に安易にプルリクエストを乱発することはパッケージのメンテナに負担をかけることになるので、以下のポイントを考慮するようにしています。
- 本当に必要な変更か確認する(すでに誰かが同様のPRを作成していないか)
- テストが通ることを確認してからPRを出す
- ドキュメントの更新が必要な場合は一緒に行う
- 前述の通りCHANGELOGの変更を忘れていました。反省。
- メンテナが理解しやすいように変更内容を明確に説明する
- 今回の例にあるプルリクエストにも説明がありませんでした。こちらも反省。
メンテナの時間と労力を尊重する姿勢も大切にしつつ、貢献していきたいです。
HerokuデプロイでGitエラー「bad line length character: fata」の解決方法
問題の概要
Herokuに新しく作成したアプリケーションにgit pushでデプロイしようとした際に、以下のようなエラーが発生しました
Enumerating objects: 14718, done. Counting objects: 100% (14718/14718), done. Delta compression using up to 16 threads Compressing objects: 100% (6495/6495), done. fatal: protocol error: bad line length character: fata Writing objects: 100% (14718/14718), 17.62 MiB | 1007.00 KiB/s, done. Total 14718 (delta 7769), reused 14137 (delta 7392), pack-reused 0 fatal: the remote end hung up unexpectedly error: failed to push some refs to 'https://git.heroku.com/example.git'
「bad line length character: fata」というエラーメッセージが表示され、Herokuへのデプロイが失敗します。
原因
この問題は、macOSでGitバージョン2.39.3を使用している場合 に発生します
解決方法
Gitのバージョンを2.39.3より上位のバージョンにアップデートすることで解消しました。
参考情報
Herokuサポートページにも同様の情報が記載されていますが、Herokuのアカウントがないと閲覧できなかったのでブログ記事にしました