参数化的dependencies
我们看到的所有dependencies都是一个固定的函数或类
但在某些情况下,您可能希望能够设置依赖项的参数,无需声明许多不同的函数或类。
假设我们需要一个依赖项来检查查询参数q是否包含一些固定内容。
但我们希望能够参数化固定内容
一个callable实例
在Python中,有一种方法可以使类的实例成为“callable”。
不是类本身(已经是可调用的),而是该类的实例。
为此,我们声明一个call方法调用:
from fastapi import Depends, FastAPIapp = FastAPI()class FixedContentQueryChecker:def __init__(self, fixed_content: str):self.fixed_content = fixed_contentdef __call__(self, q: str = ""):if q:return self.fixed_content in qreturn Falsechecker = FixedContentQueryChecker("bar")@app.get("/query-checker/")async def read_query_check(fixed_content_included: bool = Depends(checker)):return {"fixed_content_in_query": fixed_content_included}
在这个例子中,FastAPI将使用这个__call__ 来检查额外参数和子依赖项,这就是稍后在路径操作函数中将要调用的函数,以将值传递给参数。
参数化的实例
现在,我们使用__init__ 去声明实例参数,我们可以使用这些参数来”参数化”依赖关系:
from fastapi import Depends, FastAPIapp = FastAPI()class FixedContentQueryChecker:def __init__(self, fixed_content: str):self.fixed_content = fixed_contentdef __call__(self, q: str = ""):if q:return self.fixed_content in qreturn Falsechecker = FixedContentQueryChecker("bar")@app.get("/query-checker/")async def read_query_check(fixed_content_included: bool = Depends(checker)):return {"fixed_content_in_query": fixed_content_included}
在这个例子中,FastAPI永远不会触及或关心init,我们将在代码中直接使用它
创建一个实例
我们可以通过这个类创建一个实例:
from fastapi import Depends, FastAPIapp = FastAPI()class FixedContentQueryChecker:def __init__(self, fixed_content: str):self.fixed_content = fixed_contentdef __call__(self, q: str = ""):if q:return self.fixed_content in qreturn Falsechecker = FixedContentQueryChecker("bar")@app.get("/query-checker/")async def read_query_check(fixed_content_included: bool = Depends(checker)):return {"fixed_content_in_query": fixed_content_included}
这样,我们就可以参数化我们的依赖,现在有”bar”在里面作为checker.fixed_content的属性
将实例用作依赖项
然后,我们能够在Depends(checker)中使用checker,代替Depends(FixedContentQueryChecker),因为依赖checker是一个实例,不是类本身。
在解决依赖关系时,FastAPI将调用checker :
checker(q="somequery")
…并将作为路径操作函数中依赖项的值返回的任何内容作为参数fixed_content_included传递:
from fastapi import Depends, FastAPIapp = FastAPI()class FixedContentQueryChecker:def __init__(self, fixed_content: str):self.fixed_content = fixed_contentdef __call__(self, q: str = ""):if q:return self.fixed_content in qreturn Falsechecker = FixedContentQueryChecker("bar")@app.get("/query-checker/")async def read_query_check(fixed_content_included: bool = Depends(checker)):return {"fixed_content_in_query": fixed_content_included}
:::info
Tip
这一切可能显得像预谋好的。而且讲的还不是很清楚它是如何有用的。
这些例子是故意简单的,但显示了这一切是如何工作的。
在关于安全的章节中,有一些实用函数也是以这种方式实现的。
如果你了解了这些,你就已经知道下面那些安全的实用工具是如何工作的了。
:::
