エントリーから実戦までのFastAPI(10)~レスポンスモデルとステータスコード~

これまでに記録されていたのはリクエスト関連のコンテンツでしたが、この記事では、リクエスト モデルとモデルの継承、ステータス コード、その他の関連コンテンツを含む、レスポンス関連のコンテンツの記録を開始します。

基本的な応答の任意の辞書

# 任意dict构成的响应
@app06.get("/stu06/dict", response_model=Dict[str, float])
async def stu06_read_keyword_weights():
    return {
    
    "foo": 2.3, "bar": 3.4}

上記はDict宣言を使用した応答モデルですが、キーと値の種類を宣言するだけで直接応答できます。

画像-20221129181122307

基本応答モデルを定義する

# 定义一个基本模型类
class userIn(BaseModel):
    username: str
    password: str
    email: EmailStr
    sex: str
    age: int


# 响应模型:输出与输入相同的模型数据
@app06.post("/stu06/user_response", response_model=userIn)
def stu06_creat_user(user: userIn):
    return user

ここでは、などのフィールドをPydantic含む基本的なモデル クラスを定義し、リクエストを宣言し、リクエスト パラメーターのデフォルトの型を使用します。サーバーがリクエストを受信すると、受信したデータはの型で返されます。username、passwordpostQueryuserIn

画像-20221129224540214

出力応答モデルを定義する

# 添加一个输出模型类
class userOut(BaseModel):
    username: str
    email: EmailStr
    sex: Optional[str] = "girl"
    age: Optional[int] = None


# 响应输出模型
@app06.post("/stu06/userout", response_model=userOut)
def stu06_response_userout(user: userIn):
    return user

上記の例では、応答モデル クラスの役割が反映されていません。より明確に示すために、ここではクラスを再定義します。そのクラスの名前を呼び出します。上記の例と比較してパラメーターが 1 つ少なく、userOutその後password、これはpostリクエストでもあり、サーバーはuserIn型のパラメータを受け入れ、受信したデータをuserOut型として返します。応答結果にはpasswordフィールドがありません。

画像-20221129224655033

モデルの値を設定します

userItem = {
    
    
    "name1": {
    
    "username": "name1", "password": "12312312", "email": "[email protected]"},
    "name2": {
    
    "username": "name2", "password": "12312312", "email": "[email protected]", "sex": "girl", "age": 25},
    "MinChess": {
    
    "username": "MinChess", "password": "12312312", "email": "[email protected]", "sex": None,
                 "age": 22}
}


# 响应详细参数
@app06.get("/stu06/response_item", response_model=userOut)
def stu06_response_item(
        username: str = Query(...)
):
    return userItem[username]

通常、Web 開発では、応答データはデータベースに要求されます。たとえば、ユーザーがログインする場合、要求時にはユーザー名とパスワードのみが送信されます。応答時には、さらに基本的な情報が入力されて返される必要があります。事前のユーザー登録による名前、性別、年齢など。

ここでは、最初に辞書を定義します。userItem辞書keyusername値はvalue辞書ですget。次にリクエストを定義します。リクエストパラメータは ですusername。フロントエンドはusernameを使用してリクエストを送信し、サーバーがリクエストを受信した後、userItemその中で一致し、一致した後、対応するフィールドのuserOut型として返されます。

画像-20221129224833928

応答フィールド制御

未設定のパラメータを無視しますresponse_model_exclude_nset

# 响应未经参数设置的参数 response_model_exclude_nset=True
@app06.get("/stu06/response_exclude_unset", response_model=userOut, response_model_exclude_unset=True)
def stu06_response_item_exclude_unset(
        username: str = Query("name1")
):
    return userItem[username]

前の例と同様に、usernameforの場合name1、返されるフィールドはuserOutフィールド内のすべてのフィールドですが、name1名前付き辞書にはage、sexフィールドがありません。この場合、response_model_exclude_nset=Trueパラメータを設定することで制御できます。

画像-20221129224849330

応答はデフォルトを無視します response_model_exclude_defaults

# 响应忽略和默认值一样的字段 response_model_exclude_defaults=True
@app06.get("/stu06/response_exclude_defaults", response_model=userOut, response_model_exclude_defaults=True)
def stu06_response_item_exclude_defaults(
        username: str = Query("name2")
):
    return userItem[username]

同様に、データを取得して、それがデフォルトのデータと同じであることがわかった場合は、それを自動的に無視する必要があります。これはパラメータを設定することで実現できます。つまり、辞書で指定されたフィールドのデフォルト値が無視されることがresponse_model_exclude_defaults=TrueわかりますuesrItem定義された応答モデル クラスのデフォルト値と同じであるため、無視します。name2sexuserOut

もちろん、実際の状況はデフォルトの性別ではないでしょう...

画像-20221129224905361

応答無視 なしフィールド response_model_exclude_none

# 响应忽略None字段 response_model_exclude_none=True
@app06.get("/stu06/response_exclude_none", response_model=userOut, response_model_exclude_none=True)
def stu06_response_item_exclude_none(
        username: str = Query("MinChess")
):
    return userItem[username]

同様に、空のフィールドを無視する必要がある場合は、response_model_exclude_none=Trueパラメーターを設定することで実行できます。実際のアプリケーションでは、データベース内で一部のフィールドが空の場合、ユーザー エクスペリエンスに影響を与えるため、空のフィールドを直接フィルターできます。このように設定することでフィールドを;

上の例では、MinChessという名前のフィールドでsex字段为Noneは、戻りません。

画像-20221129224930523

応答には、指定されたフィールドresponse_model_includeのみが含まれます

# 响应只包含指定字段 response_model_include
@app06.get("/stu06/response_model_include", response_model=userOut, response_model_include=["username","age"])
def stu06_response_model_include(
        username:str = Query("MinChess")
):
    return userItem[username]

定義したモデルクラスはすべてのシナリオに適しているわけではありません。一部のページではアバターまたは名前だけが必要ですが、パラメータが多い場合はクラスを再定義する必要はまったくないため、上記の例のように手動で指定できます。response_model_include=["username","age"]リターンusernameageフィールド。

画像-20221129224945565

応答は指定されたフィールドresponse_model_excludeを除外します

# 响应排除指定字段 response_model_exclude
@app06.get("/stu06/response_model_exclude", response_model=userOut,response_model_exclude=["email"])
def stu06_response_model_exclude(
        username:str = Query("MinChess")
):
    return userItem[username]

上記を理解した後、これは非常に簡単です。いくつかのフィールドを無視するだけです。ここではemailフィールドを無視します。

画像-20221129225006030

モデルリスト

# 模型列表
@app06.get("/stu06/response_users",response_model=List[userOut], response_model_exclude_none=True)
def sru06_response_users(
        username1: Optional[str] = Query("name1"),
        username2: Optional[str] = Query("name2")
):
    return [userItem[username1],userItem[username2]]

モデル リストとは、応答の内容がリストであることを意味します。リストは、同じ種類のデータを大量に返す管理システムなど、定義した特定のモデル カテゴリです。しかし、実際のアプリケーションでは、それほどusername多く

ここで直接設定するだけですresponse_model。ListはクラスList类型です。userOut

画像-20221129225036700

モデルの継承

# 基本类
class loginbase(BaseModel):
    phone_number:str
    name:str
# 登录时用到的类,在此基础上,需要增加密码和验证码的字段
class login(loginbase):
    password:str
    code:str
# 登录成功后返回给前端的类,返回的字段和基本类相同,不需要增加或删除,直接pass
class loginsuccess(loginbase):
    pass
# 存储至数据库时的类,在基本模型基础上要添加一个经过处理的密码
class logindb(loginbase):
    hash_password:str
# 伪密码处理函数
def password_hash(password:str):
    return "hash——"+password
# 伪入库类:接收前端传来的login类
def login_database(loginparam:login):
    # 将接收到的login类型下loginparam中的password字段进行处理(加密)
    hashpassword = password_hash(loginparam.password)
    # 首先通过Pydantic模型的.dict()方法将loginparam处理为拥有模型数据的dict
    # 再通过**将其中的参数传递到logindb中,python对其进行解包,便能一一对应进行直接传递了
    # 同时对hash_password进行另外关键字参数的设置
    login_db = logindb(**loginparam.dict(),hash_password=hashpassword)
    print("入库成功!",login_db.dict())
    # 返回logindb类型的数据
    return login_db

@app06.post("/stu06/login",response_model=loginsuccess)
async def stu06_login(login_param:login):
    # 返回请求成功的类型的数据
    loginsuc = login_database(login_param)
    return loginsuc

実際には、この部分は主に応答に関する内容を記録するのではなく、主にアイデアを記録するものです。実際のアプリケーションでは、同じユーザー テーブルに対して、ログイン、応答、ストレージに関係するフィールドがすべて異なるため、定義することができます基本クラス を継承し、拡張機能を実装します。これにより、反復的なコードが大幅に削減されます。

具体的な知識や操作については、上記の注意事項を参照してください。非常にわかりやすくなっています。

画像-20221129225408766

ステータスコードの設定

HTTPステータスコード

HTTP ステータス コードは 3 つの 10 進数で構成され、最初の 10 進数はステータス コードの種類を定義し、最後の 2 つの数字は分類機能を持ちます。ステータス コードが異なれば、意味も異なります。

HTTPステータスコードの分類

5つのタイプがあります:

分類 カテゴリの説明
1xx 情報: サーバーはリクエストを受信し、リクエスターが操作を続行する必要があります。
2xx 成功。操作は正常に受信され、処理されました。
3xx リダイレクトされました。リクエストを完了するにはさらにアクションが必要です
4xx クライアント エラー。リクエストに構文エラーが含まれているか、完了できませんでした。
5xx サーバー エラー。リクエストの処理中にサーバーでエラーが発生しました。

一般的なステータス コードと意味

200 - 请求成功,已经正常处理完毕

301 - 请求永久重定向,转移到其它URL

302 - 请求临时重定向

304 - 请求被重定向到客户端本地缓存

400 - 客户端请求存在语法错误

401 - 客户端请求没有经过授权

403 - 客户端的请求被服务器拒绝,一般为客户端没有访问权限

404 - 客户端请求的URL在服务端不存在

500 - 服务端永久错误

デジタルクレームの直接使用

@app06.get("/stu06/statuscode",status_code=200)
async def stu06_status():
    return {
    
    "status-code":200}

上記のコードは、リクエスト ステートメント内で応答ステータス コードを 200 として直接定義しています。

画像-20221129180157668

FastAPI を使用したセットアップ

@app06.get("/stu06/statuscode_fastapi",status_code=status.HTTP_200_OK)
def stu06_fastcode():
    return {
    
    "status-code":200}

fastapi.statusこれは、次を使用して設定されるコンビニエンス変数です。

画像-20221129180401422

ソースコード

# -*- coding: utf-8 -*-
# @Time: 2022/11/29 11:17
# @Author: MinChess
# @File: stu06.py
# @Software: PyCharm

from fastapi import APIRouter, Query ,status
from pydantic import BaseModel, EmailStr, Field
from typing import Optional,List,Dict

app06 = APIRouter()

# 任意dict构成的响应
@app06.get("/stu06/dict", response_model=Dict[str, float])
async def stu06_read_keyword_weights():
    return {
    
    "foo": 2.3, "bar": 3.4}


# 定义一个基本模型类
class userIn(BaseModel):
    username: str
    password: str
    email: EmailStr
    sex: str
    age: int


# 响应模型:输出与输入相同的模型数据
@app06.post("/stu06/user_response", response_model=userIn)
def stu06_creat_user(user: userIn):
    return user


# 添加一个输出模型类
class userOut(BaseModel):
    username: str
    email: EmailStr
    sex: Optional[str] = "girl"
    age: Optional[int] = None


# 响应输出模型
@app06.post("/stu06/userout", response_model=userOut)
def stu06_response_userout(user: userIn):
    return user

userItem = {
    
    
    "name1": {
    
    "username": "name1", "password": "12312312", "email": "[email protected]"},
    "name2": {
    
    "username": "name2", "password": "12312312", "email": "[email protected]", "sex": "girl", "age": 25},
    "MinChess": {
    
    "username": "MinChess", "password": "12312312", "email": "[email protected]", "sex": None,
                 "age": 22}
}


# 响应详细参数
@app06.get("/stu06/response_item", response_model=userOut)
def stu06_response_item(
        username: str = Query(...)
):
    return userItem[username]


# 响应未经参数设置的参数 response_model_exclude_nset=True
@app06.get("/stu06/response_exclude_unset", response_model=userOut, response_model_exclude_unset=True)
def stu06_response_item_exclude_unset(
        username: str = Query("name1")
):
    return userItem[username]

# 响应忽略和默认值一样的字段 response_model_exclude_defaults=True
@app06.get("/stu06/response_exclude_defaults", response_model=userOut, response_model_exclude_defaults=True)
def stu06_response_item_exclude_defaults(
        username: str = Query("name2")
):
    return userItem[username]

# 响应忽略None字段 response_model_exclude_none=True
@app06.get("/stu06/response_exclude_none", response_model=userOut, response_model_exclude_none=True)
def stu06_response_item_exclude_none(
        username: str = Query("MinChess")
):
    return userItem[username]

# 响应只包含指定字段 response_model_include
@app06.get("/stu06/response_model_include", response_model=userOut, response_model_include=["username","age"])
def stu06_response_model_include(
        username:str = Query("MinChess")
):
    return userItem[username]

# 响应排除指定字段 response_model_exclude
@app06.get("/stu06/response_model_exclude", response_model=userOut,response_model_exclude=["email"])
def stu06_response_model_exclude(
        username:str = Query("MinChess")
):
    return userItem[username]

# 模型列表
@app06.get("/stu06/response_users",response_model=List[userOut], response_model_exclude_none=True)
def sru06_response_users(
        username1: Optional[str] = Query("name1"),
        username2: Optional[str] = Query("name2")
):
    return [userItem[username1],userItem[username2]]


# 基本类
class loginbase(BaseModel):
    phone_number:str
    name:str
# 登录时用到的类,在此基础上,需要增加密码和验证码的字段
class login(loginbase):
    password:str
    code:str
# 登录成功后返回给前端的类,返回的字段和基本类相同,不需要增加或删除,直接pass
class loginsuccess(loginbase):
    pass
# 存储至数据库时的类,在基本模型基础上要添加一个经过处理的密码
class logindb(loginbase):
    hash_password:str
# 伪密码处理函数
def password_hash(password:str):
    return "hash——"+password
# 伪入库类:接收前端传来的login类
def login_database(loginparam:login):
    # 将接收到的login类型下loginparam中的password字段进行处理(加密)
    hashpassword = password_hash(loginparam.password)
    # 首先通过Pydantic模型的.dict()方法将loginparam处理为拥有模型数据的dict
    # 再通过**将其中的参数传递到logindb中,python对其进行解包,便能一一对应进行直接传递了
    # 同时对hash_password进行另外关键字参数的设置
    login_db = logindb(**loginparam.dict(),hash_password=hashpassword)
    print("入库成功!",login_db.dict())
    # 返回logindb类型的数据
    return login_db

@app06.post("/stu06/login",response_model=loginsuccess)
async def stu06_login(login_param:login):
    # 返回请求成功的类型的数据
    loginsuc = login_database(login_param)
    return loginsuc

# 直接修改
@app06.get("/stu06/statuscode",status_code=200)
async def stu06_status():
    return {
    
    "status-code":200}

# 通过fastapi设置
@app06.get("/stu06/statuscode_fastapi",status_code=status.HTTP_200_OK)
def stu06_fastcode():
    return {
    
    "status-code":200}

読んでくれてありがとう!

ブログリンク:入門から実戦までのFastAPI (10) - レスポンスモデルとステータスコード

おすすめ

転載: blog.csdn.net/qq_45730223/article/details/128107079
おすすめ