📖 Scenario: You are building a simple FastAPI app to register users. You want to make sure the user's age is valid and the username follows specific rules.
🎯 Goal: Create a FastAPI app with a user model that uses custom validators to check the age and username fields.
📋 What You'll Learn
Create a Pydantic model called User with fields username (string) and age (integer).
Add a custom validator to ensure age is at least 18.
Add a custom validator to ensure username contains only letters and numbers.
Create a FastAPI app with a POST endpoint /register that accepts a User model.
💡 Why This Matters
🌍 Real World
Custom validators help ensure user input meets specific rules before saving or processing, improving data quality.
💼 Career
Backend developers often write custom validators in FastAPI or similar frameworks to enforce business rules and prevent bad data.
Progress0 / 4 steps
1
Create the User model with fields
Create a Pydantic model called User with two fields: username as a string and age as an integer.
FastAPI
Hint
Use class User(BaseModel): and define username and age inside.
2
Add a custom validator for age
Add a custom validator method called check_age inside the User model that ensures age is at least 18. Use the @validator('age') decorator from Pydantic.
FastAPI
Hint
Use @validator('age') and define a method that raises ValueError if age is less than 18.
3
Add a custom validator for username
Add a custom validator method called check_username inside the User model that ensures username contains only letters and numbers. Use @validator('username') and Python's isalnum() method.
FastAPI
Hint
Use @validator('username') and check if value.isalnum() is False. Raise ValueError if so.
4
Create FastAPI app with /register endpoint
Create a FastAPI app instance called app. Add a POST endpoint /register that accepts a User model as JSON and returns the same user data.
FastAPI
Hint
Create app = FastAPI(). Use @app.post('/register') and define an async function register that takes user: User and returns it.
Practice
(1/5)
1. What is the main purpose of using @validator in FastAPI models?
easy
A. To connect the model to a database
B. To automatically generate API documentation
C. To add custom rules that check if input data is valid
D. To style the API response format
Solution
Step 1: Understand the role of @validator
The @validator decorator is used to add custom validation logic to model fields in FastAPI.
Step 2: Identify the purpose of validation
Validation ensures that the data meets specific rules before the app processes it, helping keep input correct and safe.
Final Answer:
To add custom rules that check if input data is valid -> Option C
Quick Check:
Custom validation = check input rules [OK]
Hint: Validators check data rules before use [OK]
Common Mistakes:
Confusing validators with database connectors
Thinking validators generate docs
Assuming validators change response style
2. Which of the following is the correct way to define a custom validator for a Pydantic model field named age?
easy
A. @validator('age')\ndef check_age(cls, value):
B. def validate_age(cls, value):
C. @validate('age')\ndef age_validator(cls, value):
D. @validate_field('age')\ndef age_check(cls, value):
Solution
Step 1: Recall the correct decorator syntax
FastAPI uses Pydantic's @validator decorator with the field name as a string argument.
Step 2: Match the function definition style
The validator function must be a class method with parameters cls and value.
Final Answer:
@validator('age')\ndef check_age(cls, value): -> Option A
Quick Check:
Use @validator('field') with cls, value [OK]
Hint: Use @validator('field') decorator for custom checks [OK]
Common Mistakes:
Using @validate instead of @validator
Missing the field name in decorator
Wrong function parameters
3. Given this code snippet, what will be the output if age is set to 15?
from pydantic import BaseModel, validator
class User(BaseModel):
age: int
@validator('age')
def check_age(cls, value):
if value < 18:
raise ValueError('Must be 18 or older')
return value
try:
user = User(age=15)
except Exception as e:
print(e)
medium
A. Must be 18 or older
B. TypeError because age is int
C. User object with age 15 is created
D. No output, code runs silently
Solution
Step 1: Analyze the validator logic
The validator checks if age is less than 18 and raises a ValueError if true.
Step 2: Check the input value
Since age=15 is less than 18, the validator raises the error.
Final Answer:
Must be 18 or older -> Option A
Quick Check:
Age < 18 triggers ValueError [OK]
Hint: Validator raises error if condition fails [OK]
Common Mistakes:
Assuming object creates despite validation error
Confusing ValueError with TypeError
Ignoring the exception handling block
4. Identify the error in this custom validator code:
from pydantic import BaseModel, validator
class Product(BaseModel):
price: float
@validator('price')
def check_price(value):
if value <= 0:
raise ValueError('Price must be positive')
return value
medium
A. Validator method must return None
B. Missing cls parameter in validator method
C. Price field should be int, not float
D. Validator decorator should be @validate
Solution
Step 1: Check validator method signature
Validator methods must accept cls as the first parameter, then value.
Step 2: Identify missing parameter
The method check_price only has value, missing cls.
Final Answer:
Missing cls parameter in validator method -> Option B
Quick Check:
Validator needs cls, value parameters [OK]
Hint: Validator methods need cls first, then value [OK]
Common Mistakes:
Omitting cls parameter
Using wrong decorator name
Returning None instead of value
5. You want to create a custom validator that ensures a username is lowercase and at least 3 characters long. Which code correctly implements this in a FastAPI Pydantic model?
from pydantic import BaseModel, validator
class User(BaseModel):
username: str
@validator('username')
def validate_username(cls, value):
# Fill in validation logic here
pass
hard
A. if len(value) < 3 and not value.islower():\n raise ValueError('Username must be lowercase and 3+ chars')\nreturn value
B. if len(value) < 3 and value.islower():\n raise ValueError('Username too short')\nreturn value
C. if len(value) > 3 and value.islower():\n return value\nelse:\n raise ValueError('Invalid username')
D. if value.islower() and len(value) >= 3:\n return value\nraise ValueError('Username invalid')
Solution
Step 1: Understand validation requirements
The username must be lowercase and at least 3 characters long.
Step 2: Check each option logic
if value.islower() and len(value) >= 3:\n return value\nraise ValueError('Username invalid') correctly checks both conditions and raises error if not met, returning value otherwise.
Final Answer:
if value.islower() and len(value) >= 3:\n return value\nraise ValueError('Username invalid') -> Option D
Quick Check:
Check both conditions, raise error if false [OK]
Hint: Check all conditions with 'and', raise error if false [OK]
Common Mistakes:
Using 'or' instead of 'and' causing wrong logic
Returning value inside else but missing return in if
Incorrect length comparison operators
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.