FastAPI如何实现大于或小于查询参数

How to implement greater than or less than query parameters for FastAPI

我想构建一个看起来像 /cities?population__gt=100000 的端点,以获取所有人口超过 100,000 的城市。

在 FastAPI 中执行此操作的最佳方法是什么?我不想为给定字段枚举所有可能的运算符,例如:

@app.get("/cities")
def get_city(
    population: int = None,
    population_gt: int = None,
    population_gte: int = None,
    population_lt: int = None,
    population_lte: int = None):
    return ...

实现这个的一种方法是传递 operator(即 gtlt 等),并为每个操作提供一个单独的函数,您可以调用如果收到操作员。下面的例子。您可以根据需要adjust/add功能。

def gt(population):
    return f"operator: gt, population: {population}"
 
def gte(population):
    return f"operator: gte, population: {population}"
 
def lt(population):
    return f"operator: lt, population: {population}"

def lte(population):
    return f"operator: lte, population: {population}"
   
operators = {"gt": gt, "gte": gte, "lt": lt, "lte": lte}
   
@app.get("/cities")
def get_city(population: int = None, operator: str = None):
    if operator in operators:
        result = operators[operator](population)
        return result
    else:
        return "Operator Not Found!"

更新

因为正如你刚才所说的,不止一个参数需要这个,那么我建议使用类似于 this 的方法,你可以在每个键的值内传递运算符,稍后在服务器端提取它,例如 /cities?population=~gt~100000&population=~lt~500000&size=~eq~100000。您可以使用类似于上述 link 的运算符,即“等于”:~eq~、“大于”:~gt~、“大于等于”: ~gteq~ 和等等。

要为查询参数接收多个值,对于上面给出的示例URL中的population,要执行where population is greater than <number> and less than <number>等操作,可以声明一个查询参数使用类型 List 并显式使用 Query,如 here and explained in the documentation.

所述

下面的示例使用 population 参数让您了解这种方法背后的逻辑,并展示了如何在服务器端提取运算符和实际值。然后由您定义所需的其余参数,以及如何处理这些数据;例如,使用与上述方法类似的方法(每个操作都有一个函数),或者在遍历数据时构造要传递给数据库的查询。

import re
pattern = "~(.*?)~"
 
@app.get("/cities")
def get_city(population: List[str] = Query(None)):
    pop_qs = {}
    
    for p in population:
        try:
            pop_opr = re.search(pattern, p).group(1)
            pop_no_str = re.sub(r"^~.*?~", "", p)
        except:
            return "Invalid data received"
        try:
            pop_no = int(pop_no_str)
            pop_qs.update({pop_opr : pop_no})
        except ValueError:
            return f"Cannot convert '{pop_no_str}' to Integer."
            
    return pop_qs