A G*_*A G 14 python rest fastapi
在带有restframework的Django中,你可以这样做:
class Item(models.Model):
id = models.IntegerField()
name = models.CharField(max_length=32)
another_attribute = models.CharField(max_length=32)
...
(more attributes)
...
yet_another_attribute = models.CharField(max_length=32)
class ItemViewSet(viewsets.ReadOnlyModelViewSet):
permission_classes = [IsAuthenticated]
serializer_class = ItemSerializer
filterset_fields = '__all__' # <- this enables filtering on all fields
queryset = Item.objects.all()
Run Code Online (Sandbox Code Playgroud)
如果我想允许过滤,filterset_fields = '__all__'将允许我做类似的事情api/item/?(attribute)=(value)并允许我过滤任何属性
我正在阅读本教程(https://fastapi.tiangolo.com/tutorial/sql-databases/#crud-utils),看起来涉及很多手动过滤:
from fastapi_sqlalchemy import db
class Item(BaseModel):
id: int
name: str
another_attribute: str
...
(more attributes)
...
yet_another_attribute: str
# is it necessary to manually include all the fields I want to filter on as optional query parameters?
@app.get("/items/")
async def read_item(
db: Session,
id: Optional[int] = None,
name: Optional[str] = None,
another_attribute: Optional[str] = None,
...
(more attributes)
...
yet_another_attribute: Optional[str] = None
):
# and then I'd need to check if the query parameter has been specified, and if so, filter it.
queryset = db.session.query(Item)
if id:
queryset = queryset.filter(Item.id == id)
if name:
queryset = queryset.filter(Item.name == name)
if another_attribute:
queryset = queryset.filter(Item.another_attribute == another_attribute)
...
(repeat above pattern for more attributes)
...
if yet_another_attribute:
queryset = queryset.filter(Item.yet_another_attribute == yet_another_attribute)
Run Code Online (Sandbox Code Playgroud)
实现上述行为的首选方式是什么?是否有任何包可以让我免于进行大量手动过滤,从而为我提供与 Django Rest Framework 视图集一样方便的相同行为?
或者手动包含我想要过滤的所有字段作为可选查询参数,然后检查每个参数,然后过滤是否存在唯一的方法?
这是可能的,但还不完美:
from fastapi.params import Depends
@app.get("/items/")
async def read_item(item: Item = Depends()):
pass
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅FastAPI 文档。
缺点是可能需要在 Item 类中指定参数。可以编写具有所有可选参数的子类(例如,如此处所述)。它适用于该类的实例,但 FastAPI 似乎没有反映 API 文档中的内容。如果有人有解决方案,我很乐意学习。
或者,您也可以拥有多个模型,如此处所述。但我不喜欢这种方法。
要回答第二个问题,您可以访问所有通用参数,如下所示:
@app.get("/items/")
async def read_item(
db: Session,
id: Optional[int] = None,
name: Optional[str] = None,
another_attribute: Optional[str] = None,
...
(more attributes)
...
yet_another_attribute: Optional[str] = None
):
params = locals().copy()
...
for attr in [x for x in params if params[x] is not None]:
query = query.filter(getattr(db_model.Item, attr).like(params[attr]))
Run Code Online (Sandbox Code Playgroud)