Files
kmtnflower/backend/app/schemas.py
T
kfj001andClaude bd65455945 fix: resolve Pydantic date field shadowing causing 422 on event update
The field name 'date' in EventUpdate shadowed the 'date' type from
datetime, causing Pydantic v2 to interpret Optional[date] as
Optional[None] — rejecting all non-null values with a 422 error.

Fix: rename import to 'date as _date' and use '_date' in all
annotations. Also improve error handling in admin forms to properly
display 422 validation error messages.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-19 17:19:03 +00:00

115 lines
2.5 KiB
Python

from datetime import date as _date
from typing import Optional
from pydantic import BaseModel, computed_field, field_validator
# ── Program ──────────────────────────────────────────────
DAY_NAMES = {
1: "Monday",
2: "Tuesday",
3: "Wednesday",
4: "Thursday",
5: "Friday",
6: "Saturday",
7: "Sunday",
}
class ProgramCreate(BaseModel):
day_of_week: int
day_label: str
time: str
title: str
host: str
genre: str
class ProgramUpdate(BaseModel):
day_of_week: Optional[int] = None
day_label: Optional[str] = None
time: Optional[str] = None
title: Optional[str] = None
host: Optional[str] = None
genre: Optional[str] = None
class ProgramResponse(BaseModel):
id: int
day_of_week: int
time: str
title: str
host: str
genre: str
@computed_field
@property
def day_label(self) -> str:
return DAY_NAMES.get(self.day_of_week, "Unknown")
model_config = {"from_attributes": True}
# ── Event ────────────────────────────────────────────────
class EventCreate(BaseModel):
date: _date
title: str
description: str
location: str
icon: str
rsvp_url: Optional[str] = None
class EventUpdate(BaseModel):
date: Optional[_date] = None
title: Optional[str] = None
description: Optional[str] = None
location: Optional[str] = None
icon: Optional[str] = None
rsvp_url: Optional[str] = None
active: Optional[bool] = None
class EventResponse(BaseModel):
id: int
date: _date
title: str
description: str
location: str
icon: str
rsvp_url: Optional[str]
active: bool
model_config = {"from_attributes": True}
# ── DonationTier ─────────────────────────────────────────
class TierCreate(BaseModel):
name: str
amount: float
icon: str
benefits: list[str]
display_order: int
class TierUpdate(BaseModel):
name: Optional[str] = None
amount: Optional[float] = None
icon: Optional[str] = None
benefits: Optional[list[str]] = None
display_order: Optional[int] = None
class TierResponse(BaseModel):
id: int
name: str
amount: float
icon: str
benefits: list[str]
display_order: int
model_config = {"from_attributes": True}