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

FastAPI如何类似Flask request.args.get()获取查询参数并修复报错

FastAPI版本经纬度测距接口修复方案

你的代码报错、模板渲染失败是以下几个原因导致的,对应修复即可:

1. 查询参数获取逻辑错误

FastAPI实现和Flask request.args.get()等效的查询参数读取有两种写法:

  • 推荐写法:直接在路由函数的入参位置声明和查询参数同名的变量,FastAPI会自动完成URL参数解析、类型转换,还支持默认值配置
  • 兼容Flask写法:通过request.query_params.get("参数名")读取,用法和Flask的request.args.get()完全一致
    你原来的代码中没有定义Latitude1、Longitude1等四个经纬度变量就直接传入函数,所以会触发变量未定义的报错。

2. 模板渲染失败的核心原因

  • 缺失必要依赖导入:代码没有导入HTMLResponse、Jinja2Templates、Nominatim、json等依赖模块,运行时会直接抛出导入错误
  • 模板上下文传参缺失:原Flask代码渲染结果页时传入了data变量,你写的FastAPI代码没有把计算得到的data放到模板上下文中,模板读取不到变量就会渲染报错
  • 工具函数无有效返回值:原Flask代码的Travel_distance函数没有显式return结果,默认返回None,导致result == 0的无结果分支永远无法触发,遇到接口请求失败、地理编码失败的场景会直接抛异常
  • 无效语句:把!pip install这类终端执行的shell命令写在了Python代码里,会触发语法错误

修复后可直接运行的完整代码

# 先在终端执行依赖安装:pip install fastapi uvicorn requests geopy jinja2 nest-asyncio
import json
import requests
import uvicorn
import nest_asyncio
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from geopy.geocoders import Nominatim

app = FastAPI()
# 模板目录配置和原Flask逻辑保持一致,读取当前目录下的模板文件
templates = Jinja2Templates(directory="./")

@app.get("/", response_class=HTMLResponse)
async def home(request: Request):
    return templates.TemplateResponse(
        "For_putting_lat_lon.html",
        {"request": request}
    )

@app.get("/distance", response_class=HTMLResponse)
async def check(
    request: Request,
    # 自动解析URL查询参数,和Flask request.args.get效果一致
    Latitude1: str | None = None,
    Latitude2: str | None = None,
    Longitude1: str | None = None,
    Longitude2: str | None = None
):
    # 如果要完全沿用Flask的参数读取习惯,可注释上面的参数声明,改用下面4行代码
    # Latitude1 = request.query_params.get("Latitude1")
    # Latitude2 = request.query_params.get("Latitude2")
    # Longitude1 = request.query_params.get("Longitude1")
    # Longitude2 = request.query_params.get("Longitude2")

    # 参数不全直接返回无可用结果页
    if not all([Latitude1, Latitude2, Longitude1, Longitude2]):
        return templates.TemplateResponse("noavailable.html", {"request": request})
    
    data = []
    result = Travel_distance(Latitude1, Longitude1, Latitude2, Longitude2, data)
    
    if result == 0:
        return templates.TemplateResponse("noavailable.html", {"request": request})
    # 必须将计算得到的data传入模板上下文,否则模板无法读取数据
    return templates.TemplateResponse(
        "For_posting_lat_lon.html",
        {"request": request, "data": data}
    )


def Travel_distance(Latitude1, Longitude1, Latitude2, Longitude2, data):
    try:
        geolocator = Nominatim(user_agent="geoapiExercises")
        location_name1 = geolocator.geocode(f"{Latitude1}, {Longitude1}")
        location_name2 = geolocator.geocode(f"{Latitude2}, {Longitude2}")
        # 地理编码失败返回0,触发无结果页
        if not location_name1 or not location_name2:
            return 0
        
        req = requests.get(
            f"http://router.project-osrm.org/route/v1/drive/{Longitude1},{Latitude1};{Longitude2},{Latitude2}?overview=false",
            timeout=10
        )
        # OSRM接口请求失败返回0
        if req.status_code != 200:
            return 0
        route_1 = json.loads(req.content)
        # 路由数据为空返回0
        if not route_1.get("routes") or len(route_1["routes"]) == 0:
            return 0
        
        df_s = [
            location_name1,
            location_name2,
            str(route_1['routes'][0]['distance'] / 1000)
        ]
        data.append(df_s)
        return 1
    except Exception as e:
        print(f"距离计算出错:{str(e)}")
        return 0

if __name__ == "__main__":
    nest_asyncio.apply()
    uvicorn.run(app, port=8000)

补充说明

  • FastAPI的Jinja2模板渲染要求必须在上下文中传入request对象,其余模板变量的传参逻辑和Flask的render_template完全一致,只需要把变量以键值对形式写到返回的字典里即可
  • 修复版新增了异常捕获逻辑,遇到第三方接口超时、经纬度无效等场景不会直接抛出500错误,会正常返回无可用结果页面,稳定性比原Flask版本更高

内容的提问来源于stack exchange,提问作者Pooja Rajendra Prasad Tripathi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:31:11