Bird
Raised Fist0
FastAPIframework~20 mins

Custom validation with validator decorator in FastAPI - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Validator Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ component_behavior
intermediate
2:00remaining
What happens when invalid data is passed to this Pydantic model?

Consider this FastAPI Pydantic model using a @validator decorator:

from pydantic import BaseModel, validator

class User(BaseModel):
    username: str
    age: int

    @validator('age')
    def age_must_be_adult(cls, v):
        if v < 18:
            raise ValueError('Must be at least 18')
        return v

user = User(username='alice', age=16)

What will happen when this code runs?

FastAPI
from pydantic import BaseModel, validator

class User(BaseModel):
    username: str
    age: int

    @validator('age')
    def age_must_be_adult(cls, v):
        if v < 18:
            raise ValueError('Must be at least 18')
        return v

user = User(username='alice', age=16)
AIt raises a ValueError with message 'Must be at least 18' during model creation.
BIt creates the User object with age 16 without error.
CIt raises a TypeError because age is not a string.
DIt ignores the validator and sets age to 16.
Attempts:
2 left
💡 Hint

Think about what the validator function does when the age is less than 18.

📝 Syntax
intermediate
2:00remaining
Which option correctly uses the validator decorator to check multiple fields?

You want to validate that start_date is before end_date in a Pydantic model. Which code snippet correctly implements this using @validator?

FastAPI
from pydantic import BaseModel, validator
from datetime import date

class Event(BaseModel):
    start_date: date
    end_date: date

    # Your validator here
A
    @validator('end_date')
    def check_dates(cls, v, values):
        if 'start_date' in values and v &lt;= values['start_date']:
            raise ValueError('end_date must be after start_date')
        return v
B
    @validator('start_date', 'end_date')
    def check_dates(cls, v):
        if v['start_date'] &gt;= v['end_date']:
            raise ValueError('start_date must be before end_date')
        return v
C
    @validator('start_date')
    def check_dates(cls, v, values):
        if v &gt;= values['end_date']:
            raise ValueError('start_date must be before end_date')
        return v
D
    @validator('start_date', 'end_date')
    def check_dates(cls, start, end):
        if start &gt;= end:
            raise ValueError('start_date must be before end_date')
        return start
Attempts:
2 left
💡 Hint

Remember the validator receives the current field value and a dict of previously validated fields.

🔧 Debug
advanced
2:00remaining
Why does this validator not run as expected?

Look at this Pydantic model:

from pydantic import BaseModel, validator

class Product(BaseModel):
    name: str
    price: float

    @validator('price')
    def price_positive(cls, value):
        if value <= 0:
            raise ValueError('Price must be positive')

product = Product(name='Book', price=0)

Why does this code raise no error even though price is 0?

FastAPI
from pydantic import BaseModel, validator

class Product(BaseModel):
    name: str
    price: float

    @validator('price')
    def price_positive(cls, value):
        if value <= 0:
            raise ValueError('Price must be positive')

product = Product(name='Book', price=0)
AThe validator decorator is missing parentheses, so it is not applied.
BThe error is raised but caught internally by Pydantic, so no exception shows.
CThe price field is not declared as Optional, so validation is ignored.
DThe validator function does not return the value, so validation is skipped silently.
Attempts:
2 left
💡 Hint

Check what the validator function returns.

❓ state_output
advanced
2:00remaining
What is the value of 'email' after model creation?

Given this Pydantic model:

from pydantic import BaseModel, validator

class User(BaseModel):
    email: str

    @validator('email')
    def normalize_email(cls, v):
        return v.lower().strip()

user = User(email='  EXAMPLE@DOMAIN.COM  ')

What is the value of user.email?

FastAPI
from pydantic import BaseModel, validator

class User(BaseModel):
    email: str

    @validator('email')
    def normalize_email(cls, v):
        return v.lower().strip()

user = User(email='  EXAMPLE@DOMAIN.COM  ')
result = user.email
ARaises a ValueError because of whitespace
B' EXAMPLE@DOMAIN.COM '
C'example@domain.com'
D'EXAMPLE@DOMAIN.COM'
Attempts:
2 left
💡 Hint

Think about what lower() and strip() do to the string.

🧠 Conceptual
expert
2:00remaining
Which statement about Pydantic's @validator decorator is TRUE?

Choose the correct statement about how the @validator decorator works in Pydantic models.

AValidators must always be instance methods and cannot be class methods.
BValidators can access other fields' values only if those fields are validated before the current field.
CValidators run after the entire model is created and can modify any field arbitrarily.
DValidators automatically run asynchronously if the decorated method is async.
Attempts:
2 left
💡 Hint

Consider the order of field validation and how values parameter works.

Practice

(1/5)
1. What is the main purpose of using the @validator decorator in a Pydantic model within FastAPI?
easy
A. To define database relationships
B. To automatically generate API routes
C. To add custom validation logic for model fields
D. To format the output JSON response

Solution

  1. Step 1: Understand the role of @validator

    The @validator decorator is used inside Pydantic models to add custom validation logic for fields.
  2. Step 2: Differentiate from other functionalities

    It does not generate routes, define database relations, or format output JSON; those are handled elsewhere.
  3. Final Answer:

    To add custom validation logic for model fields -> Option C
  4. Quick Check:

    Custom validation = To add custom validation logic for model fields [OK]
Hint: Remember: @validator checks field values before use [OK]
Common Mistakes:
  • Confusing validation with route creation
  • Thinking it formats output JSON
  • Assuming it manages database relations
2. Which of the following is the correct syntax to create a validator for the field email in a Pydantic model?
easy
A. @validator['email']\ndef check_email(cls, value):\n return value
B. @validate('email')\ndef check_email(cls, value):\n return value
C. @validator(email)\ndef check_email(cls, value):\n return value
D. @validator('email')\ndef check_email(cls, value):\n return value

Solution

  1. Step 1: Identify correct decorator usage

    The correct decorator is @validator('field_name') with the field name as a string.
  2. Step 2: Check syntax correctness

    @validator('email')\ndef check_email(cls, value):\n return value uses @validator('email') correctly; others use wrong decorator names or syntax.
  3. Final Answer:

    @validator('email')\ndef check_email(cls, value):\n return value -> Option D
  4. Quick Check:

    Correct decorator syntax = @validator('email')\ndef check_email(cls, value):\n return value [OK]
Hint: Use quotes around field name in @validator [OK]
Common Mistakes:
  • Omitting quotes around field name
  • Using wrong decorator name like @validate
  • Using brackets [] instead of parentheses ()
3. Given the following Pydantic model, what will happen if you create an instance with age=15?
from pydantic import BaseModel, validator

class User(BaseModel):
    age: int

    @validator('age')
    def check_age(cls, v):
        if v < 18:
            raise ValueError('Must be at least 18')
        return v

user = User(age=15)
medium
A. A ValueError is raised with message 'Must be at least 18'
B. The user instance is created with age 15
C. The age is automatically set to 18
D. A TypeError is raised because age is int

Solution

  1. Step 1: Analyze the validator logic

    The validator checks if age is less than 18 and raises a ValueError if true.
  2. Step 2: Apply input value to validator

    Since age=15 is less than 18, the validator raises the error with the message.
  3. Final Answer:

    A ValueError is raised with message 'Must be at least 18' -> Option A
  4. Quick Check:

    Age < 18 triggers ValueError = A ValueError is raised with message 'Must be at least 18' [OK]
Hint: Validator raises error if condition fails [OK]
Common Mistakes:
  • Assuming instance is created despite validation error
  • Thinking age auto-corrects to 18
  • Confusing ValueError with TypeError
4. Identify the error in this validator code snippet:
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 decorator should be @validate
B. Missing cls parameter in validator method
C. Return statement is missing
D. Field name in decorator should be price without quotes

Solution

  1. Step 1: Check validator method signature

    Validator methods must have cls as the first parameter, then the value.
  2. Step 2: Identify missing parameter

    The method only has value, missing cls, causing a TypeError.
  3. Final Answer:

    Missing cls parameter in validator method -> Option B
  4. Quick Check:

    Validator method needs cls first = Missing cls parameter in validator method [OK]
Hint: Validator methods always start with cls, then value [OK]
Common Mistakes:
  • Omitting cls parameter
  • Using wrong decorator name
  • Forgetting to return the value
5. You want to create a Pydantic model that validates a username field to ensure it is at least 3 characters long and contains only letters and numbers. Which validator implementation correctly achieves this?
hard
A. from pydantic import BaseModel, validator import re class User(BaseModel): username: str @validator('username') def valid_username(cls, v): if len(v) < 3 or not re.match(r'^[a-zA-Z0-9]+$', v): raise ValueError('Username must be 3+ chars and alphanumeric') return v
B. from pydantic import BaseModel, validator class User(BaseModel): username: str @validator('username') def valid_username(cls, v): if len(v) > 3 and v.isalnum(): raise ValueError('Username must be 3+ chars and alphanumeric') return v
C. from pydantic import BaseModel, validator class User(BaseModel): username: str @validator('username') def valid_username(cls, v): if len(v) < 3 or not v.isalpha(): raise ValueError('Username must be 3+ chars and letters only') return v
D. from pydantic import BaseModel, validator import re class User(BaseModel): username: str @validator('username') def valid_username(cls, v): if len(v) < 3 or not re.match(r'^[a-z]+$', v): raise ValueError('Username must be 3+ chars and lowercase letters only') return v

Solution

  1. Step 1: Check length and character conditions

    The username must be at least 3 characters and only letters or numbers.
  2. Step 2: Evaluate each option's validation logic

    from pydantic import BaseModel, validator import re class User(BaseModel): username: str @validator('username') def valid_username(cls, v): if len(v) < 3 or not re.match(r'^[a-zA-Z0-9]+$', v): raise ValueError('Username must be 3+ chars and alphanumeric') return v correctly checks length & uses regex to allow letters and numbers only. Others either check wrong conditions or restrict letters only.
  3. Final Answer:

    Option A correctly validates username length and alphanumeric characters -> Option A
  4. Quick Check:

    Length >=3 and alphanumeric = from pydantic import BaseModel, validator import re class User(BaseModel): username: str @validator('username') def valid_username(cls, v): if len(v) < 3 or not re.match(r'^[a-zA-Z0-9]+$', v): raise ValueError('Username must be 3+ chars and alphanumeric') return v [OK]
Hint: Use regex to check alphanumeric and length together [OK]
Common Mistakes:
  • Using isalpha() instead of isalnum()
  • Checking length incorrectly (greater than vs less than)
  • Restricting to letters only when numbers allowed
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard