FastAPI:从视图名称(路由名称)中检索 URL

JPG*_*JPG 9 python python-3.x fastapi

假设我有以下观点,

from fastapi import FastAPI

app = FastAPI()


@app.get('/hello/')
def hello_world():
    return {"msg": "Hello World"}


@app.get('/hello/{number}/')
def hello_world_number(number: int):
    return {"msg": "Hello World Number", "number": number}
Run Code Online (Sandbox Code Playgroud)

我一直在 Flask 和 Django 中使用这些函数

所以,我怎样才能获得/建立的网址,hello_world并hello_world_number以类似的方式?

JPG*_*JPG 15

我们有Router.url_path_for(...)位于starlette包内的方法

方法一:使用FastAPI实例

当您能够访问FastAPI当前上下文中的实例时,此方法很有用。(感谢@Yagizcan Degirmenci)

from fastapi import FastAPI

app = FastAPI()


@app.get('/hello/')
def hello_world():
    return {"msg": "Hello World"}


@app.get('/hello/{number}/')
def hello_world_number(number: int):
    return {"msg": "Hello World Number", "number": number}


print(app.url_path_for('hello_world'))
print(app.url_path_for('hello_world_number', **{"number": 1}))
print(app.url_path_for('hello_world_number', **{"number": 2}))

# Results

/hello/
/hello/1/
/hello/2/
Run Code Online (Sandbox Code Playgroud)

退税

  • 如果我们使用APIRouter,router.url_path_for('hello_world')可能不起作用,因为router它不是FastAPI类的实例。也就是说,我们必须有FastAPI实例来解析 URL

方法 2:Request实例

当您能够访问Request实例(传入请求)时,通常在视图中,此方法很有用。

from fastapi import FastAPI, Request

app = FastAPI()


@app.get('/hello/')
def hello_world():
    return {"msg": "Hello World"}


@app.get('/hello/{number}/')
def hello_world_number(number: int):
    return {"msg": "Hello World Number", "number": number}


@app.get('/')
def named_url_reveres(request: Request):
    return {
        "URL for 'hello_world'": request.url_for("hello_world"),
        "URL for 'hello_world_number' with number '1'": request.url_for("hello_world_number", **{"number": 1}),
        "URL for 'hello_world_number' with number '2''": request.url_for("hello_world_number", **{"number": 2})
    }

# Result Response

{
    "URL for 'hello_world'": "http://0.0.0.0:6022/hello/",
    "URL for 'hello_world_number' with number '1'": "http://0.0.0.0:6022/hello/1/",
    "URL for 'hello_world_number' with number '2''": "http://0.0.0.0:6022/hello/2/"
}
Run Code Online (Sandbox Code Playgroud)

退税

  • 我们必须request在每个(或必需的)视图中包含参数来解析 URL,这可能会给开发人员带来一种难看的感觉。


Yag*_*nci 7

其实你不需要重新发明轮子。FastAPI 支持这种开箱即用的 (实际上是 Starlette),而且效果很好。

app = FastAPI()

@app.get("/hello/{number}/")
def hello_world_number(number: int):
    return {"msg": "Hello World Number", "number": number}
Run Code Online (Sandbox Code Playgroud)

如果你有这样的端点,你可以简单地使用

In:  app.url_path_for("hello_world_number", number=3)
In:  app.url_path_for("hello_world_number", number=50)

Out: /hello/3/
Out: /hello/50/
Run Code Online (Sandbox Code Playgroud)

在FastAPI 中,APIRouter和FastAPI(APIRoute)继承自Router (Starlette's) 所以,如果你有这样的APIRouter,你可以继续使用这个功能

router = APIRouter()

@router.get("/hello")
def hello_world():
    return {"msg": "Hello World"}

In:  router.url_path_for("hello_world")
Out: /hello
Run Code Online (Sandbox Code Playgroud)

  • 当您有多个路由器文件并且想要在不同文件中获取“url_path_for”路由时,您建议采用什么方法?我的 `main.py` 做了一堆 `app.include_router` 来获取所有路由。谢谢! (2认同)