Python

Verified against Claude Code · 2026-07-21

Design Pydantic v2 models that validate a real domain, not just shapes

A prompt for designing Pydantic v2 models with field constraints, cross-field validators, and deliberate optional/required decisions from a description of real-world business rules.

Claude CodeChatGPT (GPT-5.1)GitHub Copilot ChatCursor 2.1

The prompt

Ready to copy — highlighted parts are example details you can swap.

Design Pydantic v2 models for the domain below. The goal is models that reject bad data at the boundary, not models that just describe field names and types.

DOMAIN
A booking for a rental property, plus the guest making it

BUSINESS RULES TO ENFORCE
check-out date must be after check-in date; number of guests can't exceed the property's max_occupancy; a booking under 2 nights requires a minimum-stay override flag

REQUIREMENTS
1. Use Pydantic v2 syntax specifically: model_config = ConfigDict(...), not the v1-style class Config. Use Field(...) constraints (gt, max_length, pattern, etc.) for anything checkable declaratively, before reaching for a custom validator.
2. Use @field_validator for single-field logic that Field() can't express, and @model_validator(mode="after") for anything depending on more than one field (e.g. end_date must be after start_date). Name which business rule each validator enforces, in a comment.
3. Be deliberate about Optional versus required — a field should only be optional if the domain genuinely allows it to be absent, not because it's convenient during construction. Justify each optional field in one line.
4. Use Annotated[...] types for any constraint you'd otherwise repeat across multiple models, instead of copy-pasting the same Field(...) arguments everywhere.
5. Serialization: API is camelCase JSON (checkInDate), Python code should stay snake_case. If any field needs a different name on the wire than in Python, use alias or an AliasGenerator and set populate_by_name correctly, rather than manually renaming keys after the fact.
6. Give every model a docstring stating what real-world entity it represents and what invalid state it's specifically guarding against.

OUTPUT FORMAT
1. The models, in dependency order.
2. A short table: business rule, and which model or validator enforces it.
3. One example payload that should raise ValidationError, and what the error tells the caller.
Customize the highlighted detailsoptional — the prompt above already works

Why this works

Requiring Pydantic v2 syntax by name matters because a large share of tutorials and training data still show v1 patterns (class Config, the bare @validator decorator), and an underspecified prompt will produce a plausible-looking mix of both APIs that fails at import time on a v2-only install. Requiring a one-line justification for every Optional field directly counters the reflexive habit of marking everything Optional to avoid construction friction during development, which quietly defeats the entire point of using Pydantic for validation — a field that's "optional" only because it was annoying to require lets genuinely missing data flow silently downstream. Separating @field_validator from @model_validator(mode="after") by exact use case, rather than leaving the choice to the model, mirrors the real API distinction: a single-field validator literally cannot see other fields, so a cross-field rule like end date after start date has to live in the model-level validator or it can't be expressed at all.

What you get back

class BookingCreate(BaseModel): """A guest's request to book a property for a date range.""" model_config = ConfigDict(populate_by_name=True) check_in: date = Field(alias="checkInDate") check_out: date = Field(alias="checkOutDate") guest_count: int = Field(gt=0) override_min_stay: bool = False # optional: only relevant when a stay is under the minimum @model_validator(mode="after") def check_out_after_check_in(self) -> "BookingCreate": # enforces: check-out must be after check-in if self.check_out <= self.check_in: raise ValueError("check_out must be after check_in") return self Rule table: "check-out after check-in" -> check_out_after_check_in model_validator; "guest_count <= max_occupancy" -> field_validator cross-checked against the Property model at the service layer (not a static Field constraint, since it depends on another record). Invalid payload: {"checkInDate": "2026-09-10", "checkOutDate": "2026-09-09", "guestCount": 2} raises ValidationError: "check_out must be after check_in" — tells the caller exactly which rule failed, not just that the payload is invalid.

Verified against

Claude Code Sonnet 4.6 · 2026-07-21

ChatGPT GPT-5.1 · 2026-07-23

Changelog

  • 2026-07-23 Initial publish, verified against Claude Code (Sonnet 4.6) and ChatGPT (GPT-5.1) on Pydantic 2.9.

Need this built into your business?

If a prompt isn't enough — custom software, built and maintained for you — that's Scult's day job.

EXPLORE CUSTOM SOFTWARE
All Python prompts

Check your AI visibility

One URL in, a 0–100 score and the exact fixes out.

RUN THE CHECK

Browse all the tools

15 tools across six categories
13 of them never send your data anywhere

Free · No signup · No trial clock

SEE THE DIRECTORY