Django Ninja简单教程

Django Ninja

文章目录

  • Django Ninja
    • 简介
      • 特点:
      • 交换式文档
    • 教程
      • 搭建项目
      • 路由器
        • 多应用路由
        • 路由器认证
        • 路由器标签
        • 路由器嵌套
      • 请求数据
        • 路径参数
        • 请求参数
        • 请求体
        • 路径参数、查询参数和请求体
        • Form表单
        • 文件上传
      • Schema
        • 请求相关Schema(参考请求数据中)
        • 响应体Schema
        • model的Schema
        • 其他
      • 认证
        • 使用自带认证
        • 使用自定义认证
      • 操作参数
        • 标签
        • 操作:摘要
        • 操作:说明
        • OpenAPI操作ID
        • 操作:已弃用
        • 输出响应选项
        • 从架构中包含/排除操作(文档)
        • 网址名称
      • 版本控制
        • 不同的API版本号
        • 不同的业务逻辑
      • 请求解析器
        • YAML解析器
        • ORJSON 解析器
      • 响应渲染器
        • 创建渲染器
        • ORJSON渲染实例
        • XML渲染实例
      • 错误处理
        • 自定义异常处理
        • 覆盖默认异常处理程序
        • 抛出异常的HTTP响应
      • CSRF
        • 注意:将API与基于cookie的身份验证一起使用是不安全!
    • 异步支持
      • 简单介绍
      • 快速示例
      • 混合同步和异步操作
      • 弹性搜索示例
      • 使用ORM

简介

特点:

  • 简单:旨在易于使用和直观;
  • 快速执行:由于**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, alias="categories")
                
                
        @api.get("/filter")
        def events(request, filters: Filters = Query

你可能感兴趣的:(restframe,djang-ninja,django,python)