Field Metadata & Constraints
Using Field() for gt, lt, ge, le, min_length, max_length, and pattern constraints.
Type checking is great, but what if I need more specific rules? Like "age must be positive" or "name can't be empty"?
That's where Field() constraints come in. You've seen Field() for defaults — it also accepts validation parameters that restrict what values are allowed:
from pydantic import BaseModel, Field
class Product(BaseModel):
name: str = Field(min_length=1, max_length=100)
price: float = Field(gt=0)
quantity: int = Field(ge=0)
Now name must be between 1 and 100 characters, price must be greater than 0, and quantity must be greater than or equal to 0. Pydantic rejects anything that violates these rules.
What's the difference between gt and ge?
gt means "greater than" (strictly), ge means "greater than or equal to." Same pattern for the lower bound:
| Constraint | Meaning | Example |
|---|---|---|
gt=0 | > 0 | 0.01 passes, 0 fails |
ge=0 | >= 0 | 0 passes, -1 fails |
lt=100 | < 100 | 99 passes, 100 fails |
le=100 | <= 100 | 100 passes, 101 fails |
You can combine them for ranges:
class Score(BaseModel):
value: int = Field(ge=0, le=100) # 0-100 inclusive
What about string constraints? Can I enforce a specific format, like an email pattern?
Yes. For strings, you have min_length, max_length, and pattern (regex):
class UserInput(BaseModel):
username: str = Field(min_length=3, max_length=20, pattern=r"^[a-zA-Z0-9_]+$")
bio: str = Field(max_length=500, default="")
The pattern constraint uses a regular expression. Here, ^[a-zA-Z0-9_]+$ means "only letters, numbers, and underscores." If someone passes "hello world" (has a space), Pydantic rejects it.
Can I add a description to a field? Like documentation for what it represents?
Absolutely. Field() also takes description, title, and examples — these don't affect validation but show up in JSON schemas and documentation:
class Employee(BaseModel):
name: str = Field(description="Full legal name")
salary: float = Field(gt=0, description="Annual salary in USD")
department: str = Field(min_length=1, description="Department code")
These descriptions become part of the model's JSON schema, which you'll learn to generate in Phase 2. For now, they serve as inline documentation that Pydantic carries with the model.
This is like having built-in assertions on every field. No more manual if age < 0: raise ValueError?
Exactly. Every constraint you put in Field() replaces a manual check you'd otherwise write by hand. The validation runs automatically at creation time, the error messages are clear and structured, and the rules are visible right in the model definition — not buried in some validation function somewhere else.
Practice your skills
Sign up to write and run code in this lesson.
Field Metadata & Constraints
Using Field() for gt, lt, ge, le, min_length, max_length, and pattern constraints.
Type checking is great, but what if I need more specific rules? Like "age must be positive" or "name can't be empty"?
That's where Field() constraints come in. You've seen Field() for defaults — it also accepts validation parameters that restrict what values are allowed:
from pydantic import BaseModel, Field
class Product(BaseModel):
name: str = Field(min_length=1, max_length=100)
price: float = Field(gt=0)
quantity: int = Field(ge=0)
Now name must be between 1 and 100 characters, price must be greater than 0, and quantity must be greater than or equal to 0. Pydantic rejects anything that violates these rules.
What's the difference between gt and ge?
gt means "greater than" (strictly), ge means "greater than or equal to." Same pattern for the lower bound:
| Constraint | Meaning | Example |
|---|---|---|
gt=0 | > 0 | 0.01 passes, 0 fails |
ge=0 | >= 0 | 0 passes, -1 fails |
lt=100 | < 100 | 99 passes, 100 fails |
le=100 | <= 100 | 100 passes, 101 fails |
You can combine them for ranges:
class Score(BaseModel):
value: int = Field(ge=0, le=100) # 0-100 inclusive
What about string constraints? Can I enforce a specific format, like an email pattern?
Yes. For strings, you have min_length, max_length, and pattern (regex):
class UserInput(BaseModel):
username: str = Field(min_length=3, max_length=20, pattern=r"^[a-zA-Z0-9_]+$")
bio: str = Field(max_length=500, default="")
The pattern constraint uses a regular expression. Here, ^[a-zA-Z0-9_]+$ means "only letters, numbers, and underscores." If someone passes "hello world" (has a space), Pydantic rejects it.
Can I add a description to a field? Like documentation for what it represents?
Absolutely. Field() also takes description, title, and examples — these don't affect validation but show up in JSON schemas and documentation:
class Employee(BaseModel):
name: str = Field(description="Full legal name")
salary: float = Field(gt=0, description="Annual salary in USD")
department: str = Field(min_length=1, description="Department code")
These descriptions become part of the model's JSON schema, which you'll learn to generate in Phase 2. For now, they serve as inline documentation that Pydantic carries with the model.
This is like having built-in assertions on every field. No more manual if age < 0: raise ValueError?
Exactly. Every constraint you put in Field() replaces a manual check you'd otherwise write by hand. The validation runs automatically at creation time, the error messages are clear and structured, and the rules are visible right in the model definition — not buried in some validation function somewhere else.
Practice your skills
Sign up to write and run code in this lesson.