FastAPI:请求中带有时区的日期时间不起作用

Pei*_*Pei 6 python datetime pydantic fastapi

from fastapi import FastAPI
from datetime import datetime
from ..models import Contact
from ..database import Database


app = FastAPI()

# Dependency
def get_db():
    db = Database()
    try:
        yield db
    finally:
        db.disconnect()

@app.get("/contacts/", response_model=List[Contact])
async def get_contacts(address: int, start_time: datetime, end_time: datetime, duration: int, distance: int, db: Database = Depends(get_db)):
    contacts = detect_contacts(db, address, start_time, end_time, duration, distance)
    return contacts
Run Code Online (Sandbox Code Playgroud)

我正在尝试根据 ISO 8601 或 RFC 3339 获取查询参数 start_time 和 end_time 作为带有时区的日期时间值。它在没有时区的情况下工作正常,例如“2021-01-19 16:00:00”或“2021- 01-19T16:00:00”,但不包含时区,例如“2021-01-19 16:00:00+05:00”或“2021-01-19T16:00:00+05:00”,返回这样的错误:

{
    "detail": [
        {
            "loc": [
                "query",
                "start_time"
            ],
            "msg": "invalid datetime format",
            "type": "value_error.datetime"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

仅供参考,文档中明确提到它支持 datetime.datetime 类型的 ISO 8601 格式:

额外数据类型 - FastAPI

Sus*_*all 2

看到上面的评论,看起来alex_noname可能已经触及问题的核心。他展示了如何对 ISO 字符串进行编码,以便在查询参数中安全发送。

用于时区的符号+是保留字符,应编码在 url 中,否则可能会以另一种方式解释,通常为空格:例如,如果您在 google 上搜索“datetime notworking”,结果的 url 将类似于google.com/search?q=datetime+not+working

这可能是导致时区问题的原因。您可以尝试将参数打印到终端以检查其是否正确解码,您可能会看到一个空格代替加号。