해결된 질문
작성
·
78
·
수정됨
0
(강의 색션 7_8 - 14:30)
안녕하세요 선생님.
좋은 강의 만들어 공유해 주셔서 진심으로 감사드립니다.
Pydantic 모델 초기화 과정에서 아래의 코드처럼 Optional
이 설정하지 않으면 Swagger UI
에서 입력 값이 null
이여서 엔티티 타입 불일치로 422 에러가 발생합니다.
또한, parse_user_form에서 Optional 체크를 하고 Item에서는 별도로 설정하지 않으면 같은 에러가 발생하더군요.
Q) FormData 부분은 Optional 체크를 하지 않아도 되고, pydantic model에서는 반드시 Optional 체크를 해야지만 문제 없이 정상 동작하는 이유에 대한 보충 설명 부탁드려도 될까요?
주석한 부분이 기존 코드입니다. 주석한 부분으로 코드를 변경하면 에러가 발생합니다.
class Item(BaseModel):
name: str = Field(..., min_length=2, max_length=50)
# description: str = Field(None, max_length=500)
description: Optional[str] = Field(None, max_length=500)
price: float = Field(..., ge=0)
# tax: float = None
tax: Optional[float] = None
@model_validator(mode='after')
def tax_must_be_less_than_price(cls, values):
price = values.price
tax = values.tax
# if tax > price: # tax가 NoneType이라 에러가 남.
if tax is not None and tax > price:
raise ValueError("Tax must be less then price")
return values
감사합니다.
답변 1
1
안녕하십니까,
잘 듣고 계시다니, 저도 기분이 좋군요.
먼저 /items_form_02/{item_id} 엔드 포인드를 사용하신다면 tax가 Null이면 @model_validator()에서 tax > price 식 때문에 오류가 발생할 것 입니다.
tax는 제외하고 description만 말씀드리면,
async def update_item_for_02()를 보시면 Depends(parse_user_for)이 인자로 되어 있습니다.
그리고 parse_user_form() 함수의 인자를 보면
description: Annotated[str, Form(max_length=500)] = None 으로 optional 형태로 받아 들이게 되어 있습니다. 그래서 Swagger UI에서는 해당 선언만 보고 Optional 하게 선택할 수 있도록 UI가 만들어 집니다. 이후에 parse_user_form()함수는 인자로 들어온 값을 가지고 Pydantic Item 객체를 생성합니다.
그런데, Pydantic Item 객체의 선언을 보시면
description: str = Field(None, max_length=500)
으로 Optional 하지 않습니다.
요약 드리면 Swagger UI는 수행함수 인자를 보고 Optional UI를 결정하는데, 실제 Optional한 값이 들어가 버리면 Pydantic Item에서 이걸 허용하지 않기 때문에 Pydantic 오류가 발생합니다.
이건 제가 실습 코드를 좀 더 정교하게 만들었어야 하는거 아닌가 하는 생각이 듭니다. 이런 부분까지 확인하실 거라곤 생각을 못했습니다.
좋은 질문 감사드립니다.
아니에요. 충분한 설명이 됐어요. 이해했어요. 감사합니다~!
추가) 해당 질의에 대한 상세한 답변은 강의 10-7 영상의 0:45초에 설명하고 있다.