71 lines
2.2 KiB
Python
71 lines
2.2 KiB
Python
"""Pydantic schemas for Product model"""
|
|
from datetime import datetime
|
|
from decimal import Decimal
|
|
from typing import Optional
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
|
|
|
|
|
class ProductCreateRequest(BaseModel):
|
|
"""Schema for creating a new product"""
|
|
|
|
model_config = ConfigDict(
|
|
json_schema_extra={
|
|
"example": {
|
|
"name": "Handcrafted Wooden Bowl",
|
|
"description": "A beautiful handcrafted bowl made from oak",
|
|
"price": 45.99,
|
|
"stock": 10,
|
|
"image_url": "https://example.com/bowl.jpg",
|
|
}
|
|
}
|
|
)
|
|
|
|
name: str = Field(..., min_length=1, max_length=200, description="Product name")
|
|
description: Optional[str] = Field(None, description="Product description")
|
|
price: Decimal = Field(
|
|
..., gt=0, description="Product price (must be greater than 0)"
|
|
)
|
|
stock: int = Field(default=0, ge=0, description="Product stock quantity")
|
|
image_url: Optional[str] = Field(
|
|
None, max_length=500, description="Product image URL"
|
|
)
|
|
|
|
@field_validator("price")
|
|
@classmethod
|
|
def validate_price(cls, v: Decimal) -> Decimal:
|
|
"""Validate that price has at most 2 decimal places"""
|
|
if v.as_tuple().exponent < -2:
|
|
raise ValueError("Price must have at most 2 decimal places")
|
|
return v
|
|
|
|
|
|
class ProductResponse(BaseModel):
|
|
"""Schema for product response"""
|
|
|
|
model_config = ConfigDict(
|
|
from_attributes=True,
|
|
json_schema_extra={
|
|
"example": {
|
|
"id": 1,
|
|
"name": "Handcrafted Wooden Bowl",
|
|
"description": "A beautiful handcrafted bowl made from oak",
|
|
"price": 45.99,
|
|
"stock": 10,
|
|
"image_url": "https://example.com/bowl.jpg",
|
|
"is_active": True,
|
|
"created_at": "2024-01-15T10:30:00",
|
|
"updated_at": "2024-01-15T10:30:00",
|
|
}
|
|
},
|
|
)
|
|
|
|
id: int
|
|
name: str
|
|
description: Optional[str] = None
|
|
price: float
|
|
stock: int
|
|
image_url: Optional[str] = None
|
|
is_active: bool
|
|
created_at: Optional[datetime] = None
|
|
updated_at: Optional[datetime] = None
|