FastAPI 学习之路(九)请求体有多个参数如何处理?

本文介绍使用FastAPI处理带有多个参数的请求体的方法。包括如何定义请求体参数,实现可选参数,以及如何处理多个复杂的请求体参数,并展示了如何通过Body函数添加额外的请求体字段。

请求体有多个参数如何处理?

 别的不多说,我们先写一个需求,然后演示下如何展示。

需求:写一个接口,传递以下参数,书本的名称,描述,价格,打折。

接口返回返回最后的价格

我们去看下代码如何实现

from fastapi import FastAPI
from typing import Optional
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    deacription: Optional[str] = None
    price: float
    tax: Optional[float] = None


@app.put("/items")
def update_item(item: Optional[Item]):
    result = {}
    if item.tax is not None:
        total = item.price * item.tax
        result["price"] = total
        result["name"] = item.name
        return result
    result["price"] = item.price
    result["name"] = item.name
    return result

那么我们测试下,最后是否实现了这个功能,当我们输入所有的参数的时候。

最后是在我们实际的打折上返回的。

          那么我们看下,我们不增加打折如何返回

<
<think>我们正在处理用户的问题:如何在使用requests库向FastAPI发送请求时传递多个参数。 根据用户的问题,我们需要考虑在FastAPI后端中如何定义参数,以及如何使用requests库发送这些参数FastAPI支持多种参数类型,包括: 1. 路径参数(在URL路径中) 2. 查询参数(在URL的查询字符串中,即?后) 3. 请求体参数(通常在POST、PUT等请求中,以JSON、表单等形式) 4. 表单数据(multipart/form-data) 5. 文件上传 而使用requests库发送请求时,我们可以通过以下方式传递参数: - 路径参数:直接构建在URL中。 - 查询参数:使用`params`关键字参数,传递一个字典。 - 请求体参数(JSON):使用`json`关键字参数,传递一个字典。 - 表单数据:使用`data`关键字参数,传递一个字典(同时可以指定`files`用于文件上传)。 用户的问题是关于传递多个参数,因此我们需要根据参数所在的位置分别说明。 下面我们分情况讨论: 情况1:查询参数GET请求常用) 在FastAPI中,定义函数时,将参数声明为不属于路径参数的部分,它们将自动被解释为查询参数。 使用requests发送时,将参数放入`params`字典中。 情况2:请求体参数(POST、PUT等请求常用) 在FastAPI中,我们可以使用Pydantic模型来接收JSON请求体,也可以使用多个表单字段。 使用requests发送时: 如果是JSON,使用`json`参数。 如果是表单数据,使用`data`参数。 情况3:混合参数(路径参数、查询参数请求体参数) 可以同时使用。 下面我们通过示例来说明。 示例1:查询参数GET请求FastAPI代码: from fastapi import FastAPI app = FastAPI() @app.get("/items/") async def read_items(skip: int = 0, limit: int = 10): return {"skip": skip, "limit": limit} 使用requests发送: import requests params = {'skip': 0, 'limit': 20} response = requests.get("http://localhost:8000/items/", params=params) 示例2:请求体参数(JSON,POST请求FastAPI代码: from pydantic import BaseModel class Item(BaseModel): name: str description: str = None price: float tax: float = None @app.post("/items/") async def create_item(item: Item): return item 使用requests发送: import requests json_data = { "name": "Foo", "description": "An optional description", "price": 45.2, "tax": 3.5 } response = requests.post("http://localhost:8000/items/", json=json_data) 示例3:混合使用查询参数和路径参数GET请求FastAPI代码: @app.get("/items/{item_id}") async def read_item(item_id: int, q: str = None): return {"item_id": item_id, "q": q} 使用requests发送: item_id = 123 params = {'q': 'some query string'} response = requests.get(f"http://localhost:8000/items/{item_id}", params=params) 示例4:表单数据(POST请求FastAPI代码: from fastapi import Form @app.post("/login/") async def login(username: str = Form(...), password: str = Form(...)): return {"username": username} 使用requests发送: data = {'username': 'user', 'password': 'pass'} response = requests.post("http://localhost:8000/login/", data=data) 示例5:同时发送表单数据和文件(multipart/form-data) FastAPI代码: from fastapi import File, UploadFile, Form @app.post("/files/") async def create_file( file: bytes = File(...), fileb: UploadFile = File(...), token: str = Form(...), ): return { "file_size": len(file), "token": token, "fileb_content_type": fileb.content_type, } 使用requests发送: files = { 'file': open('file.txt', 'rb'), 'fileb': ('filename.bin', open('filename.bin', 'rb'), 'application/octet-stream') } data = {'token': 'secret'} response = requests.post("http://localhost:8000/files/", data=data, files=files) 注意:在发送文件时,我们使用`files`参数,同时表单数据也可以放在`data`中。 综上所述,使用requests库向FastAPI发送请求时传递多个参数,需要根据参数类型选择合适的方式: - 查询参数:使用`params` - JSON请求体:使用`json` - 表单数据:使用`data` - 文件上传:使用`files`(同时可以混合使用`data`传递其他表单字段) 因此,用户需要根据自己在FastAPI后端定义的参数类型,选择对应的requests发送方式。 另外,注意引用中提到的关于数据变量的使用(引用[1]),它可以帮助我们批量测试不同的参数,但这用户的问题是如何发送多个参数,所以我们主要关注单次请求的发送方式。 下面我们生成相关问题。</think>### 使用Requests库向FastAPI发送多参数的方法 在FastAPI中,根据参数类型和位置,需采用不同的传递方式。以下是具体实现方法: #### 1. **查询参数(URL参数)** 用于GET请求参数附加在URL后: ```python import requests # FastAPI端点示例:@app.get("/items") params = {"skip": 0, "limit": 10} response = requests.get("http://localhost:8000/items", params=params) ``` - 参数会转换为URL格式:`http://localhost:8000/items?skip=0&limit=10` - 适用于简单数据过滤和分页[^1] #### 2. **请求体参数(JSON数据)** 用于POST/PUT请求,复杂数据通过JSON传递: ```python # FastAPI端点示例:@app.post("/items") json_data = { "name": "Foo", "price": 42.0, "tags": ["electronics", "sale"] } response = requests.post("http://localhost:8000/items", json=json_data) ``` - 自动设置`Content-Type: application/json` - 适用于创建/更新对象等操作[^1] #### 3. **表单数据** 用于HTML表单提交或文件上传: ```python # FastAPI端点示例:@app.post("/login") form_data = {"username": "user1", "password": "secret"} response = requests.post("http://localhost:8000/login", data=form_data) ``` #### 4. **路径参数** 参数直接嵌入URL路径: ```python # FastAPI端点:@app.get("/items/{item_id}") item_id = 123 response = requests.get(f"http://localhost:8000/items/{item_id}") ``` #### 5. **混合参数** 组合使用多种参数类型: ```python # 路径参数 + 查询参数 + JSON体 item_id = 123 params = {"detail": True} json_data = {"status": "active"} response = requests.put( f"http://localhost:8000/items/{item_id}", params=params, json=json_data ) ``` ### 关键注意事项 1. **参数类型匹配**:确保FastAPI端点的参数声明(`Query()`, `Path()`, `Body()`)与请求方式一致 2. **嵌套数据**:复杂结构(如字典嵌套列表)必须使用JSON传递 3. **文件上传**:需使用`files`参数: ```python files = {"file": open("report.pdf", "rb")} data = {"description": "Quarterly report"} requests.post("http://localhost:8000/upload", files=files, data=data) ``` 4. **错误处理**:检查响应状态码: ```python if response.status_code != 200: print(f"Error: {response.json().get('detail')}") ``` ### 完整示例 **FastAPI端点**: ```python from fastapi import FastAPI, Query app = FastAPI() @app.post("/items/{item_id}") async def update_item( item_id: int, q: str = Query(None), # 查询参数 data: dict = Body(...) # JSON体 ): return {"item_id": item_id, "query": q, "data": data} ``` **Requests调用**: ```python import requests url = f"http://localhost:8000/items/42" params = {"q": "search_term"} json_data = {"price": 39.99, "stock": 100} response = requests.post(url, params=params, json=json_data) print(response.json()) # 输出: {"item_id":42, "query":"search_term", "data":{"price":39.99,"stock":100}} ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值