Django Ninja简单教程

Django Ninja API开发指南
Django Ninja是一个高性能的API框架,结合了Pydantic和异步支持。它提供了简单的接口,快速编码体验,以及基于OpenAPI的自动文档。本文档涵盖了从项目搭建到异步支持的详细教程,包括路由、请求数据处理、认证、错误处理和异步操作的实现。

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, alias="categories")
                
                
        @api.get("/filter")
        def events(request, filters: Filters = Query(...)):
            return {
                 
                 "filters": filters.dict()}
        
        • 注:Query()函数用来标记filters参数是查询参数。
  • 请求体
    • 使用Schema

      • from ninja import Schema
        
        
        class Item(Schema):
            name: str
            description: str = None
            price: float
            quantity: int
                
                
        @api.post("/items")
        def create(request, item: Item):
            return item
        
        • 注意:如果使用None作为默认值,则该参数可传可不传。
  • 路径参数、查询参数和请求体
    • from ninja import Schema
      
      class Item(Schema):
### Django Ninja 框架使用指南与示例 Django Ninja 是一个结合了 DjangoNinja API 的框架,旨在简化 Web 开发中的 API 创建过程。以下是关于如何安装、配置和使用 Django Ninja 的详细指南。 #### 1. 安装 DjangoDjango Ninja 在开始之前,确保已安装 DjangoDjango Ninja。可以通过以下命令完成安装: ```bash pip install django ninja ``` 安装完成后,可以创建一个新的 Django 项目或在现有项目中集成 Django Ninja[^3]。 #### 2. 配置 Django 项目 假设已经有一个 Django 项目,接下来需要将 Django Ninja 添加到项目的配置中。编辑 `settings.py` 文件,确保包含以下内容: ```python INSTALLED_APPS = [ # 其他应用 'ninja', ] ``` #### 3. 创建 API 实例 在 Django 项目中创建一个用于定义 API 的模块。例如,在 `myproject/myapp/` 目录下创建一个名为 `api.py` 的文件,并添加以下代码: ```python from ninja import NinjaAPI api = NinjaAPI() @api.get("/hello") def hello_world(request): return {"message": "Hello, World!"} ``` #### 4. 配置 URL 路由 在 `myproject/urls.py` 文件中,将 Django Ninja 的 API 路由添加到 Django 的 URL 路由系统中: ```python from django.urls import path from myapp.api import api urlpatterns = [ # 其他路由 path("api/", api.urls), ] ``` 现在,启动 Django 开发服务器并访问 `http://127.0.0.1:8000/api/hello`,应该可以看到返回的 JSON 数据[^1]。 #### 5. 示例:处理验证错误 在实际开发中,可能会遇到需要优雅处理验证错误的情况。以下是一个简单的示例,展示如何定义模型并处理验证错误: ```python from ninja import Schema, NinjaAPI api = NinjaAPI() class Item(Schema): name: str description: str = None price: float quantity: int @api.post("/items") def create_item(request, item: Item): return {"item": item.dict()} ``` 如果客户端发送的数据不符合 `Item` 模型的要求,Django Ninja 会自动返回详细的验证错误信息[^2]。 #### 6. 使用 WebSocket 进行消息推送 Django Ninja 还支持通过 WebSocket 实现实时消息推送功能。以下是一个简单的 WebSocket 配置示例: ```python from ninja_extra.websocket import WebSocketHandler class ChatHandler(WebSocketHandler): async def on_connect(self): await self.accept() async def on_receive(self, text_data=None, bytes_data=None): await self.send({"message": f"Echo: {text_data}"}) async def on_disconnect(self, close_code): pass ``` 将上述 WebSocket 处理器注册到 Django Ninja 中即可实现消息推送功能[^3]。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值