尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Django Ninja 查询参数(Query Parameters)完全指南:类型转换、默认值与 Schema 封装

Django Ninja 查询参数(Query Parameters)完全指南:类型转换、默认值与 Schema 封装 后端API设计【免费下载链接】django-ninja Fast, Async-ready, Openapi, type hints based framework for building APIs项目地址https://gitcode.com/gh_mirrors/dj/django-ninja点击查看免费下载本篇指南聚焦 Django Ninja 中GET 查询参数query parameters的声明、类型转换、校验与文档化机制。你将学会如何让函数签名中的普通参数自动成为查询参数掌握必填/可选参数的声明方式、bool/date/int等类型的转换规则以及如何使用Query[...] Schema 对复杂过滤条件进行结构化封装。读完即可在自己的 API 中写出类型安全、自动生成 OpenAPI 文档、可被编辑器与测试框架完整感知的查询参数层。查询参数的本质函数签名即参数声明在 Django Ninja 中路由处理函数除了第一个request参数外所有不属于路径参数path parameters的函数参数都会被自动解释为查询参数。这与 FastAPI 的设计一脉相承你不需要显式声明这是一个 query 参数类型注解和默认值本身就承载了全部声明信息。以 docs/src/tutorial/query/code01.py 为例weapons [Ninjato, Shuriken, Katana, Kama, Kunai, Naginata, Yari] api.get(/weapons) def list_weapons(request, limit: int 10, offset: int 0): return weapons[offset: offset limit]访问如下 URLhttp://localhost:8000/api/weapons?offset0limit10框架会从查询串中取出offset与limit按注解转换为int经校验后传入函数。这一自动推断机制的核心实现位于 ninja/signature/details.py 的_get_param_type方法。其判定优先级非常清晰参数类型是Param子类如Query(...)、Path(...)直接用该定义参数名出现在路径模板中则归为路径参数Path(...)参数是集合类型或 Pydantic 模型归为Body(...)其余所有情况一律归为Query(...)——这正是未标注即查询参数规则的源码依据。从源码结构可以推断这一优先级设计使得路径参数、查询参数、请求体三类数据源能够共存于同一函数签名互不冲突。为什么值得使用查询参数注解原文档指出查询参数与路径参数享受同样的四重收益编辑器支持Editor supportIDE 能基于函数签名给出参数提示、类型补全与重构支持杜绝魔法字符串数据解析Data parsing框架自动把 URL 查询串中的字符串解析为注解声明的 Python 类型数据校验Data validation类型不匹配或缺失必填项时自动返回 422 校验错误自动文档Automatic documentation参数会被自动录入 Swagger UI / ReDoc 的 OpenAPI schema前端与调用方可直接查看。一个关键默认行为必须牢记默认情况下GET 参数在 HTTP 层全部是字符串只有当你为函数参数加上类型注解时Django Ninja 才会将其转换为对应类型并执行校验。若不加注解参数将按str处理api.get(/weapons) def list_weapons(request, limit, offset): # type(limit) str # type(offset) str这一行为的底层逻辑同样在_get_param_type中当注解缺失时annotation self.signature.empty框架会回退为str见 ninja/signature/details.py。默认值让查询参数可省略查询参数不属于路径的固定组成部分因此天然是可选的可以设置默认值api.get(/weapons) def list_weapons(request, limit: int 10, offset: int 0): return weapons[offset : offset limit]这里默认offset0、limit10。于是访问http://localhost:8000/api/weapons等价于访问http://localhost:8000/api/weapons?offset0limit10而访问http://localhost:8000/api/weapons?offset20时函数内部拿到的参数值是offset20URL 显式设置的值limit10默认值兜底测试目录 tests/main.py 中/query/int/default路由即验证了该行为get_query_type_optional_10(request, query: int 10)在请求/query/int/default时返回foo bar 10在请求/query/int/default?query50时返回foo bar 50见 tests/test_query.py。必填与可选参数遵循 Python 函数参数语义声明查询参数必填还是可选与声明普通 Python 函数参数完全一致——没有默认值的参数就是必填的weapons [Ninjato, Shuriken, Katana, Kama, Kunai, Naginata, Yari] api.get(/weapons/search) def search_weapons(request, q: str, offset: int 0): results [w for w in weapons if q in w.lower()] return results[offset : offset 10]在上述例子中Django Ninja 会始终校验 GET 请求必须携带q参数而offset是可选整数缺省为 0。源码中必填/可选是通过Query(...)与Query(default)区分的...Ellipsis表示必填具体值表示默认值见 ninja/signature/details.py。测试用例 tests/test_query.py 给出了完整的行为矩阵请求路径状态码说明/query422缺少必填的query参数返回missing校验错误/query?querybaz200正常返回/query?not_declaredbaz422未声明的参数也会触发缺失校验声明了query但没传/query/optional200可选参数可缺省/query/int?query42.5422int注解拒绝浮点字符串返回int_parsing错误/query/int?queryfoo422非数字字符串同样被拒绝错误响应体采用标准格式例如{ detail: [ { type: missing, loc: [query, query], msg: Field required } ] }这印证了类型注解即校验规则的设计q: str缺失即报missingquery: int收到无法解析的字符串即报int_parsing。GET 参数类型转换规则声明多个不同类型的参数时转换规则各不相同from datetime import date api.get(/example) def example(request, s: str None, b: bool None, d: date None, i: int None): return [s, b, d, i]str类型原样透传不做任何转换int/float解析为对应数值类型无法解析时返回 422如/query/int?query42.5对int注解报错bool类型下面列出的任意写法大小写变体同样有效函数收到的b均为布尔值True其余写法一律视为Falsehttp://localhost:8000/api/example?b1 http://localhost:8000/api/example?bTrue http://localhost:8000/api/example?btrue http://localhost:8000/api/example?bon http://localhost:8000/api/example?byesdate类型既支持标准日期字符串也支持 unix 时间戳整数http://localhost:8000/api/example?d1577836800 # same as 2020-01-01 http://localhost:8000/api/example?d2020-01-01上述转换发生在 Pydantic 校验层。Django Ninja 在请求进入时把查询串交给Parser其中parse_querydict负责把MultiValueDictDjango 的查询字典转换为普通字典见 ninja/parser.py随后由动态构建的QueryModel通过 Pydanticmodel_validate完成类型转换与校验见 ninja/params/models.py。整个过程对开发者透明你只声明类型转换、校验、报错全由框架完成。列表型查询参数重复键的聚合查询串中可以携带重复键例如?queryaquerybqueryc。Django 的QueryDict天然支持多值Django Ninja 的Parser.parse_querydict会通过data.getlist(key)聚合这些值见 ninja/parser.py。配合List注解即可直接接收列表from typing import List from ninja import Query router.get(/query/list) def get_query_list(request, query: List[str] Query(...)): return ,.join(query)访问/query/list?queryaquerybqueryc将得到a,b,c。还可以声明可空列表router.get(/query/list-optional) def get_query_optional_list(request, query: Optional[List[str]] Query(None)): if query: return ,.join(query) return query测试矩阵覆盖了列表参数的必填/可选行为见 tests/test_query.py。在源码层面detect_collection_fields会识别注解中的集合类型并标记为列表字段parse_querydict据此决定使用getlist还是单值提取见 ninja/signature/details.py。使用 Schema 封装查询参数当查询参数增多时逐个声明函数参数会让签名臃肿。Django Ninja 支持把查询参数封装进一个 Pydantic Schema用Query[...]泛型标记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, aliascategories) api.get(/filter) def events(request, filters: Query[Filters]): return {filters: filters.dict()}关键点说明Query[Filters]表示从查询串解析出Filters实例函数内部通过filters.limit、filters.offset等属性访问各字段alias映射外部参数名URL 中使用categories如/filter?categoriesacategoriesbSchema 字段名却是category__in——这在调用方参数名与内部实现解耦时非常有用例如对接前端固定命名或 Django ORM 的__in查找语法Schema 内同样遵循默认值/必填语义limit: int 100可选且默认 100offset: int None可选且默认 None从源码看Schema 型查询参数通过_args_flatten_map的扁平化映射把 Schema 字段展开为查询键并在QueryModel.get_request_data中经parse_querydict收集数据后交给 Pydantic 校验见 ninja/signature/details.py 与 ninja/params/models.py。嵌套的 Pydantic 模型同样支持扁平化展开字段会映射为扁平键名FLATTEN_PATH_SEP分隔见 ninja/signature/details.py这为组织超多参数的复杂查询提供了可扩展方案。参数级约束与别名除了 Schema 封装还可以用Query()函数在单个参数上施加更细的约束见 ninja/params/functions.py 与 ninja/params/models.pyapi.get(/search) def search( request, q: str Query(..., min_length3, max_length50, description搜索关键词), page: int Query(1, ge1, description页码从 1 开始), size: int Query(10, ge1, le100, description每页条数), sort: str Query(name, pattern^(name|date|rating)$), categories: List[str] Query(None, aliascat), ): ...可用约束包括gt/ge/lt/le数值范围、min_length/max_length字符串长度、pattern正则、alias参数别名、title/description/example/examplesOpenAPI 文档展示、deprecated标记废弃以及include_in_schema是否显示在文档中。这些约束既作用于运行时校验也会同步写入自动生成的 OpenAPI schema让文档与校验规则永远一致。自动化文档与复杂过滤由于查询参数声明完全基于类型注解Swagger UI / ReDoc 会自动为每个查询参数生成参数说明、类型、默认值、必填标记与校验约束无需手写任何文档代码。这正是原文档强调的Automatic documentation收益在 OpenAPI 层的落地。对于更复杂的过滤场景如组合多个条件、支持__in等 Django ORM 风格查找推荐进一步阅读 过滤指南Filtering查询参数配合过滤功能可构建出既类型安全又文档完备的检索 API。小结场景写法行为基础查询参数def f(request, limit: int 10)自动识别为查询参数缺省用默认值必填参数def f(request, q: str)缺失返回 422无注解参数def f(request, x)按str处理布尔参数b: bool1/True/true/on/yes含大小写变体→True日期参数d: date支持2020-01-01或 unix 时间戳列表参数q: List[str]重复键自动聚合Schema 封装filters: Query[Filters]结构化访问 alias 映射外部名单参数约束q: str Query(..., min_length3)运行时校验 OpenAPI 文档同步Django Ninja 的查询参数体系完全由类型注解驱动解析入口是 ninja/parser.py 的parse_querydict参数分类逻辑在 ninja/signature/details.py 的_get_param_type数据模型在 ninja/params/models.py 的QueryModel而完整的必填/可选/类型/列表行为矩阵可在 tests/test_query.py 中查阅验证。掌握这套机制你就能以最小的样板代码写出校验严格、文档自动生成、前后端契约清晰的查询参数层。赞分享后端API设计【免费下载链接】django-ninja Fast, Async-ready, Openapi, type hints based framework for building APIs项目地址https://gitcode.com/gh_mirrors/dj/django-ninja点击查看免费下载相关推荐VSS SDR/Envoy路由解析视频流与代理之间如何优雅地传递请求VSS SDR/Envoy路由解析视频流与代理之间如何优雅地传递请求 在 VSSVideo Search and Summarization视频搜索与摘要人工智能大模型AI AgentRAG计算机视觉视频后端FastAPI 查询参数(Query Parameters)完全指南声明、类型转换与必填校验FastAPI 查询参数 Query Parameters 完全指南声明、类型转换与必填校验 在 FastAPI 中只要在路径操作函数里声明的参数不是路径参后端Web框架API设计FastAPI 查询参数Query Parameters完全指南自动解析、类型转换与必填校验FastAPI 查询参数Query Parameters完全指南自动解析、类型转换与必填校验 导读 本文基于 FastAPI 官方文档的韩文教程 docs后端Web框架API设计上一篇终极解决方案3分钟彻底解决Windows VC运行库缺失问题下一篇mistral.rs 运行 Gemma 3nPython SDK 多模态推理实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表