Django NinjaでAPI開発

こんにちは、グローバルウェイの平田です。

API開発のフレームワークであるDjango Ninjaを使用した、POSTリクエストでデータを登録する実装方法についてご紹介します。

※Django Ninjaの概要とGETリクエストの実装は過去の記事で紹介しています。

Django Ninjaを使ってみる

目次

この記事は以下の方を対象としています。

★4 Python開発経験が3年以上。
★3 Python開発経験が1年以上
★2 Python 初級者。簡単なプログラムコードが書けます。
★1 プログラミング未経験。

POSTリクエストでデータを登録

実装の例

まず、URLを設定します。

【urls.py】
from django.urls import path
from ninja import NinjaAPI
from api.views.views import router

api = NinjaAPI()
api.add_router(“/myapi”, router)

urlpatterns = [
    path(“v1/”, api.urls),
]

リクエストのスキーマを定義することで、Pydanticのバリデーション機能を使用した入力チェックが利用できます。以下はPOSTで送信されてきたユーザー情報が期待通りか検証し、異なる場合は自動的にJSON形式のエラーレスポンスを返却します。

【request_schema.py】
from ninja import Schema
from pydantic import constr, field_validator
import datetime
from ninja import NinjaAPI
from datetime import date

api = NinjaAPI()


class UserRequestSchema(Schema):

    name: constr(min_length=1)
    phone_no: int
    email: str = None
    birth_date: date
    role: constr(min_length=1)
    is_active: bool  

例えば、以下はphone_noが数字に変換できない文字列だった場合のレスポンスになります。

422エラー
{
    “detail”: [
        {
            “type”: “int_parsing”,
            “loc”: [
                “body”,
                “data”,
                “phone_no”
            ],
            “msg”: “Input should be a valid integer, unable to parse string as an integer”
        }
    ]
}

]

また、@field_validatorを使用すると、特定の項目のカスタムバリデーションの定義やデータの変換が可能となります。

例えばこちらは、roleが”admin”と”user”以外の場合はエラーを返却します。

    @field_validator(“role”, mode=”before”)
    def validate_role(cls, role):
        if role not in [“admin”, “user”]:
            raise ValueError(“role not found”)
        return role

以下のように日付をYYYY-MM-DDの形式に変換することも可能です。

    @field_validator(“birth_date”, mode=”before”)
    def validate_birth_date(cls, birth_date):
        birth_date = datetime.datetime.strptime(birth_date, “%Y%m%d”).date()
        return birth_date

バリデーションに成功したデータは、data(UserRequestSchema型のオブジェクト)に格納され、Userテーブルへ登録されます。

【views.py】
@router.post(“/users/”, response=UserResponseSchema)
def create_user(request, data: UserRequestSchema):
    user = User(
        name=data.name,
        phone_no=data.phone_no,
        email=data.email or None,
        birth_date=data.birth_date,
        role=data.role,
        is_active=data.is_active,
    )
    user.save()
    return user

登録に成功した際に返却するレスポンスのスキーマを定義します。

【response_schema.py】
from ninja import Schema
from ninja import Router
from datetime import date
from pydantic import constr
 
router = Router()
 
 
class UserResponseSchema(Schema):
    id: int
    name: constr(min_length=1)
    phone_no: int
    email: str = None
    birth_date: date
    role: constr(min_length=1)
    is_active: bool

実際にAPIを実行してみます。以下のようなユーザー情報でリクエストしてみます。

http://localhost:8060/v1/myapi/users/
{
    “name”: “田中太郎”,
    “phone_no”: 123456789,
    “email”: “abc@test.co.jp”,
    “birth_date”: “20010101”,
    “role”:”user”,
    “is_active”: true
}

結果、ユーザー情報がテーブルに登録され、登録された内容がレスポンスとして返却されます。

200 OK
{
    “id”: 6,
    “name”: “田中太郎”,
    “phone_no”: 123456789,
    “email”: “abc@test.co.jp”,
    “birth_date”: “2001-01-01”,
    “role”: “user”,
    “is_active”: true
}

テスト方法

Django NinjaはDjango標準のテスト機能を使用可能です。以下はTestCaseを継承して/users/エンドポイントに対してリクエストを送信し、ステータスコードとレスポンス内容を検証するテストコードの例です。

class UserRequestViewTest(TestCase):
    msg: str

    def test_user_request(self):
        client = TestClient(router)
        response = client.post(“/users/”, json=REQ_USER_DATA)
        res_user_data = response.json()
        del res_user_data[“id”]
        self.assertEqual(response.status_code, HTTPStatus.OK)
        self.assertEqual(res_user_data, RES_USER_DATA)  

リクエストデータ

REQ_USER_DATA = {
    “name”: “string”,
    “phone_no”: 123456789,
    “email”: “abc@test.co.jp”,
    “birth_date”: “20010101”,
    “role”: “admin”,
    “is_active”: True,
}

期待するレスポンスデータ

RES_USER_DATA = {
    “name”: “string”,
    “phone_no”: 123456789,
    “email”: “abc@test.co.jp”,
    “birth_date”: “2001-01-01”,
    “role”: “admin”,
    “is_active”: True,
}

まとめ

POSTリクエストを送信→データの検証→テーブル登録→レスポンス返却までの実装方法と、テスト方法について紹介しました。

今回の記事を読んでDjango Ninjaに興味を持たれた方は、参考文献に記載しているDjango Ninjaの公式ドキュメントをご覧いただき、さらに理解を深めてみてください。

参考文献

Django Ninja – Fast Django REST Framework

この記事が気に入ったら
いいね または フォローしてね!

  • URLをコピーしました!
  • URLをコピーしました!
目次