30 Ngày Chinh Phục FastAPI - [Ngày 3]
Ngày 3: Pydantic và Validate Dữ liệu
1. Giới thiệu về Pydantic
1.1. Là gì?
Pydantic là một thư viện Python giúp chúng ta quản lý và kiểm tra dữ liệu một cách dễ dàng và hiệu quả. Hãy tưởng tượng Pydantic như một người bạn rất thông minh, giúp chúng ta kiểm tra xem các món đồ chơi (dữ liệu) có đúng như chúng ta muốn hay không.
- Nó là một cách để nói với máy tính rằng "mình muốn dữ liệu phải như thế này nè!"
- Ví dụ, mình muốn tên của một món đồ chơi phải là chữ, giá của nó phải là số.
- Nếu ai đó đưa cho mình một món đồ chơi mà tên lại là số, hoặc giá lại là chữ, Pydantic sẽ nói "Không được đâu! Cái này không đúng!"
- Nhờ Pydantic, code của mình sẽ dễ đọc hơn, giống như một cuốn truyện tranh có hình ảnh minh họa vậy đó!
Túm lại:
- Kiểu dữ liệu: Pydantic sử dụng "type hints" (gợi ý kiểu) của Python để nói với máy tính rằng "tôi muốn dữ liệu phải như thế này".
- Kiểm tra dữ liệu: Nếu ai đó đưa cho chúng ta một món đồ chơi không đúng kiểu, Pydantic sẽ thông báo lỗi ngay lập tức.
- Rõ ràng và dễ đọc: Nhờ Pydantic, code của chúng ta sẽ giống như một cuốn sách dễ hiểu, không bị rối mắt.
1.2. Tại sao cần?
Pydantic giúp chúng ta đảm bảo rằng mọi thứ đều hoạt động trơn tru. Đây là những lý do chính:
- Đảm bảo tính chính xác: Dữ liệu luôn ở định dạng mà chúng ta mong muốn.
- Ngăn ngừa lỗi: Giúp tránh những lỗi gây ra bởi dữ liệu không hợp lệ.
- Tài liệu API chính xác: Tạo ra tài liệu cho API rõ ràng và dễ hiểu hơn.
- Cải thiện trải nghiệm người dùng: Người dùng sẽ có trải nghiệm tốt hơn khi mọi thứ hoạt động đúng.
2. Thực chiến
2.1. Cách để định nghĩa Model Pydantic:
Cài thư viện Pydantic bằng lệnh:
pip install pydantic
Để tạo ra một Pydantic Model, mình sẽ tạo ra một "khuôn mẫu" để tạo ra các đối tượng dữ liệu.
- Đầu tiên, mình tạo một "ngôi nhà" (class) đặc biệt bằng cách kế thừa từ
pydantic.BaseModel
. - Sau đó, mình "trang trí" ngôi nhà bằng các thuộc tính, ví dụ như
name
,description
,price
,tax
. - Mình cũng cần nói cho Pydantic biết mỗi thuộc tính là loại gì, ví dụ
name
là chữ (string),price
là số (float). - Nếu một thuộc tính nào đó có thể không có (ví dụ, không phải món đồ chơi nào cũng có "description"), mình có thể dùng
typing.Optional
hoặc| None
để nói với Pydantic rằng "thuộc tính này có thể không có". - Mình cũng có thể đặt giá trị mặc định cho các thuộc tính, ví dụ nếu không ai nói gì về
tax
, mình sẽ mặc định nó là 0.
# Định nghĩa một Pydantic Model
from typing import Optional
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Optional[str] = None #Hoặc description: str | None = None (từ Python 3.10)
price: float
tax: Optional[float] = None #Hoặc tax: float | None = None (từ Python 3.10)
name: str
: Thuộc tínhname
phải là một chuỗi (text).description: str | None = None
: Thuộc tínhdescription
có thể là một chuỗi (text) hoặc không có gì (None
). Nếu không ai nói gì, nó sẽ làNone
.price: float
: Thuộc tínhprice
phải là một số (ví dụ: 10.5, 20.0).tax: float | None = None
: Thuộc tínhtax
có thể là một số hoặc không có gì. Nếu không ai nói gì, nó sẽ làNone
.
Mình có thể tạo ra những "ngôi nhà" phức tạp hơn bằng cách lồng các Pydantic Model vào nhau. Giống như mình xây một tòa lâu đài bằng LEGO, mình cần nhiều viên gạch LEGO khác nhau vậy đó! Đôi khi, người ta còn gọi Pydantic Model là "model" hoặc "schema".
2.2. Bài tập thực hành
Bài tập 1: Tạo Model cho Người dùng
=> Hãy tạo một Pydantic Model cho người dùng (User) với các thuộc tính sau:
username
: chuỗi (string)email
: chuỗi (string)full_name
: chuỗi (string) có thể là Noneage
: số nguyên (integer) có thể là None
# Định nghĩa User Model
from pydantic import BaseModel
from typing import Optional
class User(BaseModel):
username: str
email: str
full_name: Optional[str] = None
age: Optional[int] = None
Bài tập 2: Kiểm tra dữ liệu
Hãy viết một hàm để kiểm tra xem một đối tượng User
có hợp lệ hay không. Sử dụng model mà con vừa tạo ở bài tập 1.
def create_user(user_data):
try:
user = User(**user_data)
print("User created successfully:", user)
except Exception as e:
print("Error:", e)
# Thử nghiệm với dữ liệu hợp lệ
create_user({
"username": "john_doe",
"email": "john@example.com",
"full_name": "John Doe",
"age": 30
})
# Thử nghiệm với dữ liệu không hợp lệ
create_user({
"username": "jane_doe",
"email": "jane@example.com",
"full_name": "Jane Doe",
"age": "thirty" # Đây là lỗi, age phải là số nguyên
})
2.3. Bài tập nâng cao
Bài tập 3: Lồng nhiều Models vào nhau
Hãy tạo một model cho địa chỉ (Address) và lồng nó vào model User
. Địa chỉ sẽ có các thuộc tính sau:
street
: chuỗi (string)city
: chuỗi (string)state
: chuỗi (string)zip_code
: chuỗi (string)
class Address(BaseModel):
street: str
city: str
state: str
zip_code: str
class UserWithAddress(BaseModel):
username: str
email: str
full_name: Optional[str] = None
age: Optional[int] = None
address: Address
# Thử nghiệm với UserWithAddress Model
create_user_with_address({
"username": "john_doe",
"email": "john@example.com",
"full_name": "John Doe",
"age": 30,
"address": {
"street": "123 Main St",
"city": "Anytown",
"state": "CA",
"zip_code": "12345"
}
})
2.4. Kết
Pydantic giúp chúng ta định nghĩa cấu trúc dữ liệu rõ ràng và kiểm tra tính hợp lệ của dữ liệu trước khi sử dụng. Học được cách định nghĩa model, kiểm tra dữ liệu và lồng nhiều model vào nhau. Bài tiếp theo sẽ là - Ngày 4: Swagger UI, Query Parameters, Path Parameters
All rights reserved