python fastapi如何接收前端的时间

 
 
 
在 Python FastAPI 中,接收前端时间最推荐、最优雅的方式是使用 Python 内置的 datetime 类型进行自动解析。FastAPI 会依靠 Pydantic 自动将前端传来的 ISO 8601 格式字符串(例如 2026-08-30T22:50:00)转换成 Python 的 datetime 对象。
主要有以下三种常见场景:
1. 通过路径参数(Path)或查询参数(Query)接收
适用于 GET 请求或简单的参数传递。
python
from datetime import datetime
from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/items/")
async def read_items(
    # 前端传参示例: /items/?start_time=2026-08-30T22:50:00
    start_time: datetime = Query(None, description="开始时间")
):
    return {"parsed_time": start_time, "type": str(type(start_time))}
请谨慎使用此类代码。
2. 通过请求体(Body)接收
适用于 POSTPUT 等请求,通常将时间包裹在 Pydantic 模型中。
python
from datetime import datetime
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Event(BaseModel):
    name: str
    event_time: datetime  # Pydantic 会自动验证并解析时间

@app.post("/events/")
async def create_event(event: Event):
    # 前端发送 JSON: {"name": "会议", "event_time": "2026-08-30T22:50:00Z"}
    return {"message": f"项目 {event.name} 创建成功", "time": event.event_time}
请谨慎使用此类代码。
3. 前端传参的标准格式
为了确保 FastAPI 能够无缝解析,前端发送时间时应遵循 ISO 8601 标准。以下格式均可被正确识别:
  • 仅日期: 2026-08-30
  • 日期与时间: 2026-08-30T22:50:00
  • 带有时区(推荐): 2026-08-30T22:50:00+08:002026-08-30T14:50:00Z

如果你需要处理更特殊的时间交互,我们可以进一步讨论:
  • 前端无法提供标准 ISO 格式,需要自定义时间解析格式?
  • 如何处理时区转换(感知型时区 vs 无时区限制)?
  • 需要接收纯时间(time)或纯日期(date)?
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
前端无法提供标准 ISO 格式,需要自定义时间解析格式
 
 
 
 
 
当前端无法提供标准 ISO 格式(例如传入了 2026/08/30 22:50:002026年08月30日),最优雅的解决方案是利用 Pydantic 的 BeforeValidator(前置校验器) 或 field_validator,在数据进入业务逻辑前将其手动解析为标准 datetime 对象。
以下是针对请求体(Body)和查询参数(Query)的具体实现方式:
1. 请求体(Body)接收:使用 Pydantic 自定义解析
如果前端通过 JSON 传参,可以在 Pydantic 模型中拦截并使用 datetime.strptime 解析自定义格式。
python
from datetime import datetime
from typing import Annotated
from fastapi import FastAPI
from pydantic import BaseModel, BeforeValidator

app = FastAPI()

# 1. 定义解析函数(如果解析失败,抛出 ValueError,Pydantic 会自动返回 422 错误)
def parse_custom_datetime(v: str) -> datetime:
    if isinstance(v, datetime):
        return v
    # 假设前端格式为: "2026/08/30 22:50:00"
    return datetime.strptime(v, "%Y/%m/%d %H:%M:%S")

# 2. 创建一个可复用的自定义时间类型
CustomDateTime = Annotated[datetime, BeforeValidator(parse_custom_datetime)]

class Appointment(BaseModel):
    title: str
    # 使用自定义的时间类型
    booking_time: CustomDateTime

@app.post("/appointments/")
async def create_appointment(data: Appointment):
    # 前端发送 JSON: {"title": "看牙医", "booking_time": "2026/08/30 22:50:00"}
    return {
        "title": data.title,
        "parsed_time": data.booking_time,      # 已经是标准 datetime 对象
        "type": str(type(data.booking_time))   # <class 'datetime.datetime'>
    }
请谨慎使用此类代码。
2. 查询参数(Query)接收:使用 Depends 依赖注入
如果前端是通过 URL 拼接(如 /search?time=2026/08/30)传入自定义格式,FastAPI 无法直接应用 Pydantic 校验器。此时使用 依赖注入(Depends) 是最干净的解法。
python
from datetime import datetime
from fastapi import FastAPI, Query, HTTPException, status

app = FastAPI()

# 定义一个依赖项函数
def get_custom_date(
    date_str: str = Query(..., alias="date", description="格式: YYYY/MM/DD")
) -> datetime:
    try:
        # 假设前端格式为: "2026/08/30"
        return datetime.strptime(date_str, "%Y/%m/%d")
    except ValueError:
        raise HTTPException(
            status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
            detail="时间格式错误,请使用 YYYY/MM/DD 格式"
        )

@app.get("/search/")
async def search_by_date(
    # 使用 Depends 注入解析后的时间
    target_date: datetime = Depends(get_custom_date)
):
    # 前端请求: /search?date=2026/08/30
    return {"query_date": target_date, "type": str(type(target_date))}
请谨慎使用此类代码。

如果你确定了前端的具体格式,我可以帮你直接写出对应的 %Y-%m-%d 格式化字符串。请问前端目前计划采用哪种具体的时间文本格式?
 
 
 

posted on 2026-08-30 23:54  漫思  阅读(21)  评论(0)    收藏  举报

导航