Day 11 · ~13m

Model Configuration

Using model_config for aliases, populate_by_name, strict mode, and extra field handling.

🧑‍💻

The data I'm working with has field names like firstName and last-name — they don't match Python naming conventions. How do I handle that?

👩‍🏫

With aliases. You can tell Pydantic to accept a different name in the input data while keeping a Pythonic field name in your model:

from pydantic import BaseModel, Field

class User(BaseModel):
    first_name: str = Field(alias="firstName")
    last_name: str = Field(alias="lastName")
    age: int

# Input uses camelCase, model uses snake_case
user = User(firstName="Alice", lastName="Smith", age=30)
print(user.first_name)  # "Alice"

The alias is the external name (what the data source uses). The field name is the internal name (what your Python code uses).

🧑‍💻

What if I want to use either the alias or the field name? Like sometimes my data has firstName and sometimes first_name?

👩‍🏫

Enable populate_by_name in the model config:

from pydantic import ConfigDict

class User(BaseModel):
    model_config = ConfigDict(populate_by_name=True)

    first_name: str = Field(alias="firstName")
    last_name: str = Field(alias="lastName")
    age: int

# Both work now
u1 = User(firstName="Alice", lastName="Smith", age=30)
u2 = User(first_name="Alice", last_name="Smith", age=30)

model_config = ConfigDict(...) is how you set model-wide configuration. It's a class-level dictionary of settings.

🧑‍💻

What happens if someone passes extra fields that aren't in the model? Like {"name": "Alice", "age": 30, "color": "blue"}?

👩‍🏫

By default, Pydantic ignores extra fields. But you can change this with the extra setting:

from pydantic import ConfigDict

class StrictUser(BaseModel):
    model_config = ConfigDict(extra="forbid")
    name: str
    age: int

# This raises ValidationError — "color" is not a valid field
try:
    StrictUser(name="Alice", age=30, color="blue")
except Exception as e:
    print("Extra field rejected!")

The three options are "ignore" (default), "forbid" (raise error), and "allow" (store them).

🧑‍💻

Is there a way to make the model freeze its values? Like making it immutable after creation?

👩‍🏫

Yes. Use frozen=True:

class Config(BaseModel):
    model_config = ConfigDict(frozen=True)
    host: str
    port: int

c = Config(host="localhost", port=8080)
# c.port = 9090  # This would raise an error!

Frozen models can't be modified after creation. This is useful for configuration objects, database records, or any data that shouldn't change once validated.

🧑‍💻

Can I combine multiple config options?

👩‍🏫

Yes, just pass them all to ConfigDict:

class ApiResponse(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
        extra="forbid",
        frozen=True,
        str_strip_whitespace=True
    )
    status_code: int = Field(alias="statusCode")
    message: str

str_strip_whitespace=True automatically strips whitespace from all string fields — no need for individual validators. Config options let you set policies at the model level instead of repeating them on every field.

Practice your skills

Sign up to write and run code in this lesson.

Already have an account? Sign in