You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Litestar的GET路由中使用Pydantic模型作为查询参数

问题

我尝试在Litestar中创建一个GET路由,将Pydantic模型用作查询参数,但序列化未按预期工作。以下是复现问题的最小示例:

from pydantic import BaseModel
from litestar import Litestar, get, Controller


class Input(BaseModel):
    foo: str
    bar: str


class RootController(Controller):
    path = "/"

    @get()
    def input(self, input: Input) -> str:
        return input.foo + input.bar


app = Litestar(route_handlers=[RootController])

发送如下GET请求:

import httpx
import json

params = {
    "input": {
        "foo": "test",
        "bar": "this"
    }
}

def prepare_encode(params: dict) -> dict:
    for key, value in params.items():
        if isinstance(value, dict):
            params[key] = json.dumps(value, indent=None)
    return params

params = prepare_encode(params)
response = httpx.get("http://localhost:8000/", params=params)
response.json()

请求返回如下错误:

{
    "status_code": 400,
    "detail": "Validation failed for GET /?input=%7B%22foo%22%3A%20%22test%22%2C%20%22bar%22%3A%20%22this%22%7D",
    "extra": [
        {
            "message": "Input should be a valid dictionary or instance of Input"
        }
    ]
}

看起来查询参数未被正确序列化为Input Pydantic模型。

我已尝试的操作:

  • 使用json.dumps将字典编码后作为参数发送
  • 调试Litestar模型实现,发现查询参数以字符串形式传入msgspec转换,不符合所需类型

预期行为:
期望input查询参数能被正确解析并序列化为Input模型,使GET请求成功且无验证错误。

问题:
如何在Litestar的GET路由中正确传递Pydantic模型作为查询参数?我在序列化过程中遗漏了什么?这是否可行?

额外环境信息:

  • Litestar版本:2.10.0
  • Pydantic版本:2.8.2
  • httpx版本:0.27.0
解决方案

在Litestar中处理GET请求的复杂查询参数(比如Pydantic模型),需要注意参数的传递格式和Litestar的解析配置,以下是具体解决方法:

方法一:使用扁平的查询参数(推荐)

GET请求的查询参数通常是键值对形式,Litestar默认会自动将同模型的扁平参数绑定到Pydantic模型,不需要嵌套传递,直接把模型字段作为顶级参数发送:

修改请求代码

import httpx

params = {
    "foo": "test",
    "bar": "this"
}

response = httpx.get("http://localhost:8000/", params=params)
print(response.text)  # 输出 "testthis"

路由代码无需修改

原有的Input模型和路由处理函数保持不变,Litestar会自动将foo和bar参数映射到Input模型实例中。

方法二:启用嵌套查询参数解析

如果必须使用嵌套的input参数名传递,需要在Litestar中配置允许嵌套查询参数,并调整请求的传递方式:

1. 修改路由配置,启用嵌套解析

在@get装饰器中添加nested_query_parameters=True:

class RootController(Controller):
    path = "/"

    @get(nested_query_parameters=True)
    def input(self, input: Input) -> str:
        return input.foo + input.bar

2. 调整请求参数格式

不需要用json.dumps序列化,直接传递嵌套字典,httpx会自动将其转换为input[foo]和input[bar]形式的查询参数:

import httpx

params = {
    "input": {
        "foo": "test",
        "bar": "this"
    }
}

response = httpx.get("http://localhost:8000/", params=params)
print(response.text)  # 输出 "testthis"

原代码失败原因

原代码用json.dumps把嵌套字典序列化为字符串传递,Litestar收到的是一个JSON格式的字符串,而不是它期望的字典结构。即使启用了嵌套解析,Litestar也不会自动将JSON字符串反序列化为字典,因此触发了验证错误。

内容的提问来源于stack exchange,提问作者casabre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 12:57:07