ปกติถ้าหากจำนวน Fields ใน Form มีไม่มากก็ไม่มีปัญหาเราสามารถเขียนแบบปกติได้ เช่น


@app.post("/abc", response_model=bool)
def abc(id: int = Form(...), name: str = Form(default=None),status: str = Form(default="single")):
  return True
Enter fullscreen mode Exit fullscreen mode

แต่ถ้า Fields มีเยอะ ๆ สัก 10 Fields ขึ้นไป Code ก็จะเริ่มดูยากยาวมาก การใช้ Pydantic model เข้ามาช่วยก็จะจัดการง่ายขึ้น ปกติเราใช้ Pydantic model ใน Body แบบ JSON กันอยู่แล้วแต่สำหรับ Form Data จะมีลูกเล่นนิดหนึ่ง ค้นหาใน internet ไปเจอวิธีที่คิดว่าง่ายที่สุดละเลยบันทึกไว้สักหน่อย

ต้นฉบับที่ผมนำมาใช้

stackoverflow

ตัวอย่าง model.py

from typing import Optional

from fastapi import Form
from pydantic import BaseModel


def form_body(cls):
    cls.__signature__ = cls.__signature__.replace(
        parameters=[
            arg.replace(default=Form(default=arg.default) if arg.default is not inspect._empty else Form(...))
            for arg in cls.__signature__.parameters.values()
        ]
    )
    return cls

@form_body
class Profile(BaseModel):
    passport_no: Optional[str]
    hn: Optional[str]
    patient_guid: Optional[str]
    prefix: str = "นาย"
    first_name: str
    last_name: str
    prefix_eng: str = "Mr"
    first_name_eng: Optional[str]
    middle_name_eng: Optional[str]
    last_name_eng: Optional[str]
    gender: int = 1
    birth_date: Optional[str]
    mobile_phone: Optional[str]
    installed_line_connect: Optional[str]
    address: Optional[str]
    moo: Optional[str]
    road: Optional[str]
    chw_code: Optional[str]
    amp_code: Optional[str]
    tmb_code: Optional[str]
    address_full_thai: Optional[str]
    address_full_english: Optional[str]
    nationality: Optional[str]

Enter fullscreen mode Exit fullscreen mode

ในส่วนของ Form มันจะมีหลัก ๆ อยู่สามแบบคือ

  • บังคับ
  • มีค่า Default
  • มีก็ได้ไม่มีก็ได้

ผมเลยปรับในตัว Decorators เพิ่มเติมให้มันปรับตาม Model ที่เรากำหนดไว้

arg.replace(default=Form(default=arg.default) if arg.default is not inspect._empty else Form(...))
Enter fullscreen mode Exit fullscreen mode

ตัวอย่าง Router

from model import Profile
from fastapi import Depends, FastAPI, File, UploadFile

app = FastAPI()

@app.post("/abc", response_model=bool)
def abc(profile: Profile = Depends(Profile), photo: UploadFile = File(...)):

  return True

Enter fullscreen mode Exit fullscreen mode

ตอน Render ก็จะได้ประมาณนี้

Swagger

Swagger input with default

ลองเอาไปประยุกต์ใช้กันดูครับ

Logo

Python社区为您提供最前沿的新闻资讯和知识内容

更多推荐