Django Ninja
简介
特点:
- 简单:旨在易于使用和直观;
- 快速执行:由于**Pydantic和异步支持,**性能非常高;
- 快速编码:类型提示和自动文档让您只关注业务逻辑;
- 基于标准:基于 API 的开放标准:OpenAPI(以前称为 Swagger)和JSON Schema;
- Django 友好:(显然)与 Django 核心和 ORM 有很好的集成;
- 生产就绪:多家公司在实时项目中使用。
交换式文档
- 启动项目,然后访问http://127.0.0.1:8000/api/docs;
- 看到自动的交互式API文档(由OpenAPI/Swagger UI提供)。
教程
搭建项目
-
安装
-
pip install django-ninja
-
-
创建django项目
-
python django-admin startproject myproject
-
-
单应用项目
-
应用创建应用urls.py同目录下的api.py(也可以直接在view.py中实现)
-
from ninja import NinjaAPI api = NinjiaAPI() @api.get("/hello") def hello(request): dosomething
-
-
在url.py配置url路由
-
from django.contrib import admin from django.urls import path from .api import api urlpatterns = [ path("admin/", admin.site.urls), path("api/", api.urls) ]
-
-
请求方法选择。如果一个方法一个处理函数,直接使用
@api.get(path)
;如果是多个方法一个处理函数,则使用@api.api_operation(method, path)
。其中,method用列表表示。
-
路由器
-
多应用路由
-
当有多个应用时,在每个应用中的创建一个api.py模块(或者直接在views.py模块)中写各自的路由.
-
from ninja import Router from .models import xxx router = Router() @router.get("/") def list_events(request): return [ { "id": elem.id, "title": elem.title} for elem in xxx.objects.all() ]
-
-
在项目文件夹urls.py中实现多个应用的router注册
-
from ninja import NinjaAPI from xxx.api import router as xxx_router from yyy.api import router as yyy_router api = NinjaAPI() api.add_router("/xxx/", xxx_router) api.add_router("/yyy/", yyy_router) urlpatterns = [ path("admin/", admin.site.urls), path("api/v1/", api.urls) ]
-
-
-
路由器认证
-
api.add_router("/xxx/", xxx_router, auth=BasicAuth()) # or we can write as this # router = Router(auth=BasicAuth())
-
-
路由器标签
-
可以使用tags参数将标签应用于路由器声明的操作。
-
api.add_router("/xxx/", xxx_router, tags=["xxx"]) # or we can write as this # router = Router(tags=["xxx"])
-
-
-
路由器嵌套
-
from django.contrib import admin from django.urls import path from ninja import NinjaAPI, Router API = NinjaAPI() first_router = Router() second_router = Router() third_router = Router() @api.get("/add") def add(request, a: int, b: int): return { "result": a+ b} @first_router.get("/add") def add(request, a: int, b: int): return { "result": a+ b} @second_router.get("/add") def add(request, a: int, b: int): return { "result": a+ b} @third_router.get("/add") def add(request, a: int, b: int): return { "result": a+ b} second_router.add_router("l3", third_router) first_router.add_router("l2", second_router) api.add_router("l1", first_router) urlpatterns = [ path("admin/", admin.site.urls), path("api/", api.urls), ] # 以上路由可有以下路径 # /api/add # /api/l1/add # /api/l1/l2/add # /api/l1/l2/l3/add
-
请求数据
-
路径参数
-
所有的路径参数都会按照给定的类型自动转化,如果转化失败,则报错。
-
常规python格式化字符串形式
-
# 不指定参数类型,默认为字符串 @api.get("/items/{item_id}") def read_item(request, item_id): return { "item_id": item_id} # 指定参数类型 @api.get("/items/{item_id}") def read_item(request, item_id: int): return { "item_id": item_id}
-
-
django路径参数转换器
-
@api.get("/items/{int:item_id}") def read_item(request, item_id): return { "item_id": item_id}
-
注:{int:item_id}之间不允许有空格,有空格会报错。
-
-
使用Schema
-
import datetime from ninja import Schema, Path class PathSchema(Schema): year: int month: int day: int def value(self): return datetime.date(self.year, self.month, self.day) @api.get("/events/{year}/{month}/{day}") def events(request, date: PathSchema = Path(...))
- 注:Path()函数用来标记date参数是路径参数。
-
-
-
请求参数
-
请求参数分为两种:位置参数和可选参数。
-
位置参数。不给定参数类型,则默认为字符串类型。
-
@api.get("/weapons") def list_weapons(request, limit, offset): # type(limit) == str # type(offset) == str
-
-
可选参数。通过给定参数默认值实现。
-
@api.get("/weapons") def list_weapons(request, limit: int = 10, offset: int = 0): return weapons[offset:offset+limit]
-
-
位置参数和可选参数。
-
@api.get("/weapons/search") def search_weapons(request, keyword: str, offset: int = 0): results = [w for w in weapons if keyword in w.lower()] return results[offset: offset+10]
-
-
使用Schema
-
import datetime from typing import List from pydantic import Field from ninja import Query, Schema class Filters(Schema): limit: int = 100 offset: int = None query: str = None category__in: List[str] = Field(None
-
-