Python WebAcademy

Python WebAcademy Blog

Django Ninja 1.8がリリース。DjangoでFastAPIのようにAPIを作れるツールに、Webhookの記述と省略できる検索条件の改善が入ったニュースを初心者向けに解説

|

2026年11月8日、DjangoでFastAPIのような書き方でAPIを作れるDjango Ninjaの1.8.0が公開されました。Webhookで送るデータの形をOpenAPIの説明書に書けるようになり、省略できる検索条件をまとめたスキーマが、何も送られなかったときに422のエラーにならなくなっています。1.7.3と1.8.0で同じAPIを動かした結果とともに整理します。

2026年11月8日、DjangoでFastAPIのような書き方でAPIを作れるライブラリDjango Ninjaの1.8.0が公開されました。11月5日のベータ版1.8.0b1を経ての正式版です。

今回の目玉は、Webhookで送るデータの形を、OpenAPIと呼ばれるAPIの説明書に書けるようになったことです。また、省略できる検索条件をまとめたスキーマが、何も送られなかったときに、エラーではなくNoneになるよう直されました。

ほかにも、動きが変わる点がいくつか挙げられています。今回は、1.7.3と1.8.0で同じAPIを動かしながら、何が変わったのかを見ていきます。

まずはDjango Ninjaとはどんなものか

最初に、Django Ninjaを知らない方のために、どんなライブラリなのかを簡単に紹介します。Django Ninjaは、DjangoでAPIを作るための追加のライブラリです。

APIとは、プログラム同士がデータをやりとりするための窓口のことです。Django Ninjaでは、型ヒントを書くだけで、受け取るデータの検証や、APIの説明書の作成までを自動で行ってくれます。

最小のAPIを動かしてみた

まずは、どんな書き方なのかを見ておきましょう。商品の名前と値段を受け取って、登録したことにするだけの小さなAPIです。

from ninja import NinjaAPI, Schema

api = NinjaAPI()


class Item(Schema):
    name: str
    price: int


@api.post("/items")
def create_item(request, item: Item):
    return {"message": f"{item.name}を{item.price}円で登録しました"}

1.8.0を入れた仮想環境で、テスト用のClientから、正しいデータと、値段に文字を入れたデータを送ってみました。

200 {'message': 'りんごを120円で登録しました'}
422 Input should be a valid integer, unable to parse string as an integer

値段に安いという文字を送ると、整数ではないという422のエラーが自動で返りました。型ヒントを書くだけで、受け取るデータの検証まで済むのが、このライブラリの持ち味です。

FastAPIとの関係

型ヒントで受け取るデータを決める書き方は、FastAPIとよく似ています。どちらも、データの検証にPydanticというライブラリを使っています。

項目 FastAPI Django Ninja
土台 Starlette Django
データの検証 Pydantic Pydantic
APIの説明書 OpenAPIを自動で作成 OpenAPIを自動で作成
向いている場面 APIだけの新しいサービス Djangoの管理画面やORMをそのまま使いたいとき

すでにDjangoで作ったサイトに、APIを足したいときに便利な選択肢です。FastAPIについては、こちらで紹介しています。【関連記事】PythonのFastAPIとは?

Djangoそのものの基本は、こちらで紹介しています。【関連記事】PythonのDjangoとは?

1.8で何が変わったのかを整理しよう

続いて、1.8.0の主な変更を表にまとめます。内容は、Django NinjaのGitHubにある1.8.0のリリースノートにもとづいています。

分類 主な変更
新機能 Webhookで送るデータの形を、OpenAPIの説明書に書ける
新機能 ドキュメントを、Quick Start、Tutorial、Guide、Aboutに整理
改善 省略できるスキーマの検索条件が、何も送られないときNoneに
改善 ファイルと一緒に送られた値を、型に合わせて読むように
対応範囲 Python 3.15を、Django 5.2、6.0、6.1と組み合わせて検証

ドキュメントの整理では、TaskFlowという作業管理アプリを8回に分けて作るチュートリアルが加わりました。AIのアシスタントが読みやすいように、llms.txtというファイルも用意されています。

リリースノートには、Python、Django、Pydanticの最低限の版が変わったという記載はありませんでした。Python 3.15で動かしたい方には、嬉しい知らせです。

省略できる検索条件が、422にならなくなった

まずは、多くの人に関係しそうな修正から見ていきましょう。検索のAPIでは、カテゴリーや値段の範囲などの条件を、1つのスキーマにまとめて受け取ることがよくあります。

リリースノートによると、こうした省略できるスキーマを、QueryやHeader、Formの引数として使ったとき、どの項目も送られなかった場合は、既定値が使われるようになりました。これまでは、422のエラーになることがあったそうです。

1.7.3と1.8.0で試してみた

実際に試してみましょう。カテゴリーを必須、最低価格を省略できる項目にした検索条件のスキーマを、まるごと省略できる形で受け取るAPIを作りました。

from ninja import NinjaAPI, Query, Schema

api = NinjaAPI()


class Filters(Schema):
    category: str
    min_price: int = 0


@api.get("/products")
def products(request, filters: Filters | None = Query(None)):
    return {"filters": filters.dict() if filters else None}

Django 5.2と組み合わせ、1.7.3と1.8.0をそれぞれ新しい仮想環境に入れて、テスト用のClientから呼び出しました。手元のPython 3.11で実行した結果です。

django-ninja 1.7.3
/api/products 422 {"detail": [{"type": "missing", "loc": ["query", "category"], "msg": "Field required"}]}
/api/products?category=fruit 200 {"filters": {"category": "fruit", "min_price": 0}}

django-ninja 1.8.0
/api/products 200 {"filters": null}
/api/products?category=fruit 200 {"filters": {"category": "fruit", "min_price": 0}}

1.7.3では、条件をまるごと省略したつもりなのに、categoryが足りないという422のエラーになりました。1.8.0では、省略されたものとしてNoneが渡され、ふつうに200で応答しています。

すべての項目に既定値があるときは

ちなみに、categoryにも既定値を付けて同じことを試すと、1.7.3では{"category": "all", "min_price": 0}と、既定値の入ったスキーマが渡されました。1.8.0では、この場合もNoneになりました。

つまり1.8.0では、何も送られなかったときは、中身の既定値ではなく、引数の既定値のNoneが使われるようになったわけです。既定値の入ったスキーマを前提にしていたコードは、上げたあとに確かめておきましょう。

Webhookの形を、説明書に書けるようになった

続いて、新機能のWebhookです。Webhookとは、何かが起きたときに、こちらから相手のサーバーへ通知を送る仕組みのことです。

たとえば、注文の支払いが終わったら、取引先のシステムへお知らせを送る、といった使い方をします。送る側は、どんな形のデータを送るのかを、相手に伝えておく必要があります。

試しに書いてみた

リリースノートによると、@api.webhookをスキーマのクラスに付けると、そのデータの形が、OpenAPI 3.1の説明書のwebhooksという欄に書かれます。実際に試してみました。

@api.webhook("order.paid")
class OrderPaid(Schema):
    """注文の支払いが終わったときに送る通知"""
    order_id: int
    amount: int

1.8.0で、作られた説明書のwebhooksの欄を取り出した結果です。一部を短くしています。

"order.paid": {
  "post": {
    "summary": "Order Paid",
    "requestBody": {
      "content": {
        "application/json": {
          "schema": {"$ref": "#/components/schemas/OrderPaid"}
...

1.7.3では、webhookという機能がまだないので、AttributeErrorになりました。リリースノートには、これは説明書を書くための機能で、Django Ninjaが実際に通知を送るわけではない、とも明記されています。

送る処理そのものは、requestsなどで自分で書く必要があります。【関連記事】Pythonのrequestsとは?

動きが変わる点

リリースノートには、上げると動きが変わる点も、まとめて書かれています。初心者にも関係しそうなものを表にまとめます。

変更 中身
ModelSchemaの並び順 モデルの項目が先、自分で足した項目が後になり、応答のキーの順番が変わる
二重の指定 自分で定義した項目をMeta.fieldsにも並べると、DeprecationWarningが出る
外部キーの型 to_fieldで文字列の項目を指定した外部キーは、文字列として扱われる
空になりうる関係 null=Trueの外部キーなどは、スキーマでもOptionalになる
設定の削除 NINJA_PAGINATION_MAX_OFFSETがなくなり、残っていても無視される

ModelSchemaとは、Djangoのモデルから、APIで使うスキーマを自動で作る仕組みです。応答のキーの順番に頼ったテストがある場合は、上げたあとに失敗するかもしれません。

警告は、将来のエラーの予告

2つ目の二重の指定について、リリースノートには、将来はConfigErrorというエラーになる予定だと書かれています。今のうちに警告を直しておくと、次の版で慌てずに済みます。

Pydanticでの型の扱いについては、こちらで紹介しています。【関連記事】Pydantic v2とは?

上げる前にやっておきたいこと

最後に、Django Ninjaを1.8.0へ上げる前に確かめておきたいことを整理します。

順番 確認すること
1 省略できるスキーマの引数で、既定値の入ったスキーマを前提にしていないか
2 応答のキーの順番に頼ったテストがないか
3 DeprecationWarningが出ていないか
4 NINJA_PAGINATION_MAX_OFFSETを設定していないか

私は10年ほどエンジニアとして開発に関わってきましたが、検索条件を省略しただけで422が返るAPIに、利用者から問い合わせが続いたことがあります。何も指定しなければ全件を返す、という自然な動きにしやすくなったのは、使う側にとっても作る側にとってもありがたい変更です。

まとめ

2026年11月8日、Django Ninja 1.8.0が公開されました。Webhookで送るデータの形をOpenAPIの説明書に書けるようになり、省略できる検索条件のスキーマが、何も送られなかったときに422ではなくNoneになるよう改善されています。

ModelSchemaの並び順など、動きが変わる点もあります。上げたら、まずテストを流して、警告が出ていないかを確かめておきましょう。

ここまでお読みいただきありがとうございました。

参考情報

次のアクション

記事で学んだ内容を実際に動かしてみよう

Python WebAcademyでは、ブラウザ上でコードを書きながら基礎から実践まで体系的に学べます。

Python WebAcademyの学習画面

あわせて読む

関連記事

ブログ一覧へ

Python学習ロードマップ

まずはこの3講座から

記事で気になったテーマを、順番に手を動かしながら学べます。

ロードマップを見る