[{"data":1,"prerenderedAt":991},["ShallowReactive",2],{"nav":3,"page-\u002Fadvanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide\u002Fmodel-config-vs-class-config\u002F":310,"surround-\u002Fadvanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide\u002Fmodel-config-vs-class-config\u002F":989},[4,96,212],{"title":5,"path":6,"stem":7,"children":8},"Advanced Pydantic Validation Serialization","\u002Fadvanced-pydantic-validation-serialization","advanced-pydantic-validation-serialization",[9,12,30,42,54,66,90],{"title":10,"path":6,"stem":11},"Advanced Pydantic Validation and Serialization","advanced-pydantic-validation-serialization\u002Findex",{"title":13,"path":14,"stem":15,"children":16},"Custom Validators and Field Constraints in Pydantic","\u002Fadvanced-pydantic-validation-serialization\u002Fcustom-validators-field-constraints","advanced-pydantic-validation-serialization\u002Fcustom-validators-field-constraints\u002Findex",[17,18,24],{"title":13,"path":14,"stem":15},{"title":19,"path":20,"stem":21,"children":22},"Creating Reusable Custom Validators in Pydantic","\u002Fadvanced-pydantic-validation-serialization\u002Fcustom-validators-field-constraints\u002Fcreating-reusable-custom-validators-in-pydantic","advanced-pydantic-validation-serialization\u002Fcustom-validators-field-constraints\u002Fcreating-reusable-custom-validators-in-pydantic\u002Findex",[23],{"title":19,"path":20,"stem":21},{"title":25,"path":26,"stem":27,"children":28},"Pydantic v2 Async Custom Validator: What to Do Instead","\u002Fadvanced-pydantic-validation-serialization\u002Fcustom-validators-field-constraints\u002Fpydantic-v2-async-custom-validator","advanced-pydantic-validation-serialization\u002Fcustom-validators-field-constraints\u002Fpydantic-v2-async-custom-validator\u002Findex",[29],{"title":25,"path":26,"stem":27},{"title":31,"path":32,"stem":33,"children":34},"JSON Schema Customization in Pydantic and FastAPI","\u002Fadvanced-pydantic-validation-serialization\u002Fjson-schema-customization","advanced-pydantic-validation-serialization\u002Fjson-schema-customization\u002Findex",[35,36],{"title":31,"path":32,"stem":33},{"title":37,"path":38,"stem":39,"children":40},"Customizing OpenAPI Schema Generation in FastAPI","\u002Fadvanced-pydantic-validation-serialization\u002Fjson-schema-customization\u002Fcustomizing-openapi-schema-generation-in-fastapi","advanced-pydantic-validation-serialization\u002Fjson-schema-customization\u002Fcustomizing-openapi-schema-generation-in-fastapi\u002Findex",[41],{"title":37,"path":38,"stem":39},{"title":43,"path":44,"stem":45,"children":46},"Nested Model Serialization in FastAPI","\u002Fadvanced-pydantic-validation-serialization\u002Fnested-model-serialization","advanced-pydantic-validation-serialization\u002Fnested-model-serialization\u002Findex",[47,48],{"title":43,"path":44,"stem":45},{"title":49,"path":50,"stem":51,"children":52},"Handling Deeply Nested JSON Models Efficiently","\u002Fadvanced-pydantic-validation-serialization\u002Fnested-model-serialization\u002Fhandling-deeply-nested-json-models-efficiently","advanced-pydantic-validation-serialization\u002Fnested-model-serialization\u002Fhandling-deeply-nested-json-models-efficiently\u002Findex",[53],{"title":49,"path":50,"stem":51},{"title":55,"path":56,"stem":57,"children":58},"Performance Optimization for Pydantic Models in FastAPI","\u002Fadvanced-pydantic-validation-serialization\u002Fperformance-optimization-for-models","advanced-pydantic-validation-serialization\u002Fperformance-optimization-for-models\u002Findex",[59,60],{"title":55,"path":56,"stem":57},{"title":61,"path":62,"stem":63,"children":64},"Pydantic Model Serialization Performance in FastAPI","\u002Fadvanced-pydantic-validation-serialization\u002Fperformance-optimization-for-models\u002Fpydantic-model-serialization-performance","advanced-pydantic-validation-serialization\u002Fperformance-optimization-for-models\u002Fpydantic-model-serialization-performance\u002Findex",[65],{"title":61,"path":62,"stem":63},{"title":67,"path":68,"stem":69,"children":70},"Pydantic V2 Migration Guide for FastAPI","\u002Fadvanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide","advanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide\u002Findex",[71,72,78,84],{"title":67,"path":68,"stem":69},{"title":73,"path":74,"stem":75,"children":76},"Migrate @validator to @field_validator in Pydantic v2","\u002Fadvanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide\u002Fmigrate-validator-to-field-validator","advanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide\u002Fmigrate-validator-to-field-validator\u002Findex",[77],{"title":73,"path":74,"stem":75},{"title":79,"path":80,"stem":81,"children":82},"Migrating from Pydantic v1 to v2 Without Breaking APIs","\u002Fadvanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide\u002Fmigrating-from-pydantic-v1-to-v2-without-breaking-apis","advanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide\u002Fmigrating-from-pydantic-v1-to-v2-without-breaking-apis\u002Findex",[83],{"title":79,"path":80,"stem":81},{"title":85,"path":86,"stem":87,"children":88},"model_config vs class Config in Pydantic v2","\u002Fadvanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide\u002Fmodel-config-vs-class-config","advanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide\u002Fmodel-config-vs-class-config\u002Findex",[89],{"title":85,"path":86,"stem":87},{"title":91,"path":92,"stem":93,"children":94},"Type Hinting and IDE Integration in FastAPI","\u002Fadvanced-pydantic-validation-serialization\u002Ftype-hinting-ide-integration","advanced-pydantic-validation-serialization\u002Ftype-hinting-ide-integration\u002Findex",[95],{"title":91,"path":92,"stem":93},{"title":97,"path":98,"stem":99,"children":100},"Async Background Tasks Observability","\u002Fasync-background-tasks-observability","async-background-tasks-observability",[101,104,122,140,158,176,194],{"title":102,"path":98,"stem":103},"Async, Background Tasks, and Observability in FastAPI","async-background-tasks-observability\u002Findex",{"title":105,"path":106,"stem":107,"children":108},"Async Correctness and Concurrency in FastAPI","\u002Fasync-background-tasks-observability\u002Fasync-correctness-concurrency","async-background-tasks-observability\u002Fasync-correctness-concurrency\u002Findex",[109,110,116],{"title":105,"path":106,"stem":107},{"title":111,"path":112,"stem":113,"children":114},"FastAPI async def vs def: Performance and When to Use Each","\u002Fasync-background-tasks-observability\u002Fasync-correctness-concurrency\u002Ffastapi-async-def-vs-def-performance","async-background-tasks-observability\u002Fasync-correctness-concurrency\u002Ffastapi-async-def-vs-def-performance\u002Findex",[115],{"title":111,"path":112,"stem":113},{"title":117,"path":118,"stem":119,"children":120},"Fixing Blocking Calls in Async FastAPI Routes","\u002Fasync-background-tasks-observability\u002Fasync-correctness-concurrency\u002Ffixing-blocking-calls-in-async-routes","async-background-tasks-observability\u002Fasync-correctness-concurrency\u002Ffixing-blocking-calls-in-async-routes\u002Findex",[121],{"title":117,"path":118,"stem":119},{"title":123,"path":124,"stem":125,"children":126},"Async Database Sessions in FastAPI","\u002Fasync-background-tasks-observability\u002Fasync-database-sessions","async-background-tasks-observability\u002Fasync-database-sessions\u002Findex",[127,128,134],{"title":123,"path":124,"stem":125},{"title":129,"path":130,"stem":131,"children":132},"Async SQLAlchemy Session per Request in FastAPI","\u002Fasync-background-tasks-observability\u002Fasync-database-sessions\u002Fasync-sqlalchemy-session-per-request","async-background-tasks-observability\u002Fasync-database-sessions\u002Fasync-sqlalchemy-session-per-request\u002Findex",[133],{"title":129,"path":130,"stem":131},{"title":135,"path":136,"stem":137,"children":138},"Fixing asyncpg Connection Pool Exhaustion in FastAPI","\u002Fasync-background-tasks-observability\u002Fasync-database-sessions\u002Ffixing-asyncpg-pool-exhaustion","async-background-tasks-observability\u002Fasync-database-sessions\u002Ffixing-asyncpg-pool-exhaustion\u002Findex",[139],{"title":135,"path":136,"stem":137},{"title":141,"path":142,"stem":143,"children":144},"Background Task Processing in FastAPI","\u002Fasync-background-tasks-observability\u002Fbackground-task-processing","async-background-tasks-observability\u002Fbackground-task-processing\u002Findex",[145,146,152],{"title":141,"path":142,"stem":143},{"title":147,"path":148,"stem":149,"children":150},"FastAPI BackgroundTasks vs Celery vs ARQ","\u002Fasync-background-tasks-observability\u002Fbackground-task-processing\u002Ffastapi-backgroundtasks-vs-celery-vs-arq","async-background-tasks-observability\u002Fbackground-task-processing\u002Ffastapi-backgroundtasks-vs-celery-vs-arq\u002Findex",[151],{"title":147,"path":148,"stem":149},{"title":153,"path":154,"stem":155,"children":156},"Running ARQ Workers with FastAPI","\u002Fasync-background-tasks-observability\u002Fbackground-task-processing\u002Frunning-arq-workers-with-fastapi","async-background-tasks-observability\u002Fbackground-task-processing\u002Frunning-arq-workers-with-fastapi\u002Findex",[157],{"title":153,"path":154,"stem":155},{"title":159,"path":160,"stem":161,"children":162},"Caching Strategies in FastAPI","\u002Fasync-background-tasks-observability\u002Fcaching-strategies","async-background-tasks-observability\u002Fcaching-strategies\u002Findex",[163,164,170],{"title":159,"path":160,"stem":161},{"title":165,"path":166,"stem":167,"children":168},"Cache Invalidation Patterns in FastAPI","\u002Fasync-background-tasks-observability\u002Fcaching-strategies\u002Fcache-invalidation-patterns-in-fastapi","async-background-tasks-observability\u002Fcaching-strategies\u002Fcache-invalidation-patterns-in-fastapi\u002Findex",[169],{"title":165,"path":166,"stem":167},{"title":171,"path":172,"stem":173,"children":174},"Redis Response Caching in FastAPI","\u002Fasync-background-tasks-observability\u002Fcaching-strategies\u002Fredis-response-caching-in-fastapi","async-background-tasks-observability\u002Fcaching-strategies\u002Fredis-response-caching-in-fastapi\u002Findex",[175],{"title":171,"path":172,"stem":173},{"title":177,"path":178,"stem":179,"children":180},"Observability and Tracing in FastAPI","\u002Fasync-background-tasks-observability\u002Fobservability-and-tracing","async-background-tasks-observability\u002Fobservability-and-tracing\u002Findex",[181,182,188],{"title":177,"path":178,"stem":179},{"title":183,"path":184,"stem":185,"children":186},"Instrumenting FastAPI with OpenTelemetry","\u002Fasync-background-tasks-observability\u002Fobservability-and-tracing\u002Finstrumenting-fastapi-with-opentelemetry","async-background-tasks-observability\u002Fobservability-and-tracing\u002Finstrumenting-fastapi-with-opentelemetry\u002Findex",[187],{"title":183,"path":184,"stem":185},{"title":189,"path":190,"stem":191,"children":192},"Structured JSON Logging with Request IDs in FastAPI","\u002Fasync-background-tasks-observability\u002Fobservability-and-tracing\u002Fstructured-json-logging-with-request-ids","async-background-tasks-observability\u002Fobservability-and-tracing\u002Fstructured-json-logging-with-request-ids\u002Findex",[193],{"title":189,"path":190,"stem":191},{"title":195,"path":196,"stem":197,"children":198},"Rate Limiting and Throttling in FastAPI","\u002Fasync-background-tasks-observability\u002Frate-limiting-throttling","async-background-tasks-observability\u002Frate-limiting-throttling\u002Findex",[199,200,206],{"title":195,"path":196,"stem":197},{"title":201,"path":202,"stem":203,"children":204},"FastAPI Rate Limiting with Redis and SlowAPI","\u002Fasync-background-tasks-observability\u002Frate-limiting-throttling\u002Ffastapi-rate-limiting-with-redis-slowapi","async-background-tasks-observability\u002Frate-limiting-throttling\u002Ffastapi-rate-limiting-with-redis-slowapi\u002Findex",[205],{"title":201,"path":202,"stem":203},{"title":207,"path":208,"stem":209,"children":210},"Per-User Token Bucket Throttling in FastAPI","\u002Fasync-background-tasks-observability\u002Frate-limiting-throttling\u002Fper-user-token-bucket-throttling","async-background-tasks-observability\u002Frate-limiting-throttling\u002Fper-user-token-bucket-throttling\u002Findex",[211],{"title":207,"path":208,"stem":209},{"title":213,"path":214,"stem":215,"children":216},"Core Architecture Routing Patterns","\u002Fcore-architecture-routing-patterns","core-architecture-routing-patterns",[217,220,232,250,268,280,292],{"title":218,"path":214,"stem":219},"FastAPI Core Architecture and Routing Patterns","core-architecture-routing-patterns\u002Findex",{"title":221,"path":222,"stem":223,"children":224},"Application Factory Patterns in FastAPI","\u002Fcore-architecture-routing-patterns\u002Fapplication-factory-patterns","core-architecture-routing-patterns\u002Fapplication-factory-patterns\u002Findex",[225,226],{"title":221,"path":222,"stem":223},{"title":227,"path":228,"stem":229,"children":230},"FastAPI App Factory Pattern for Testing and Deployment","\u002Fcore-architecture-routing-patterns\u002Fapplication-factory-patterns\u002Ffastapi-app-factory-pattern-for-testing-and-deployment","core-architecture-routing-patterns\u002Fapplication-factory-patterns\u002Ffastapi-app-factory-pattern-for-testing-and-deployment\u002Findex",[231],{"title":227,"path":228,"stem":229},{"title":233,"path":234,"stem":235,"children":236},"Configuration Management in FastAPI","\u002Fcore-architecture-routing-patterns\u002Fconfiguration-management","core-architecture-routing-patterns\u002Fconfiguration-management\u002Findex",[237,238,244],{"title":233,"path":234,"stem":235},{"title":239,"path":240,"stem":241,"children":242},"Managing Environment Variables with Pydantic Settings","\u002Fcore-architecture-routing-patterns\u002Fconfiguration-management\u002Fmanaging-environment-variables-with-pydantic-settings","core-architecture-routing-patterns\u002Fconfiguration-management\u002Fmanaging-environment-variables-with-pydantic-settings\u002Findex",[243],{"title":239,"path":240,"stem":241},{"title":245,"path":246,"stem":247,"children":248},"Pydantic Settings vs Dynaconf vs python-decouple","\u002Fcore-architecture-routing-patterns\u002Fconfiguration-management\u002Fpydantic-settings-vs-dynaconf-vs-python-decouple","core-architecture-routing-patterns\u002Fconfiguration-management\u002Fpydantic-settings-vs-dynaconf-vs-python-decouple\u002Findex",[249],{"title":245,"path":246,"stem":247},{"title":251,"path":252,"stem":253,"children":254},"Dependency Injection Strategies in FastAPI","\u002Fcore-architecture-routing-patterns\u002Fdependency-injection-strategies","core-architecture-routing-patterns\u002Fdependency-injection-strategies\u002Findex",[255,256,262],{"title":251,"path":252,"stem":253},{"title":257,"path":258,"stem":259,"children":260},"Best Practices for FastAPI Dependency Injection","\u002Fcore-architecture-routing-patterns\u002Fdependency-injection-strategies\u002Fbest-practices-for-fastapi-dependency-injection","core-architecture-routing-patterns\u002Fdependency-injection-strategies\u002Fbest-practices-for-fastapi-dependency-injection\u002Findex",[261],{"title":257,"path":258,"stem":259},{"title":263,"path":264,"stem":265,"children":266},"Fixing FastAPI Dependency Injection Circular Imports","\u002Fcore-architecture-routing-patterns\u002Fdependency-injection-strategies\u002Ffastapi-dependency-injection-circular-import-fix","core-architecture-routing-patterns\u002Fdependency-injection-strategies\u002Ffastapi-dependency-injection-circular-import-fix\u002Findex",[267],{"title":263,"path":264,"stem":265},{"title":269,"path":270,"stem":271,"children":272},"Error Handling and Global Exceptions in FastAPI","\u002Fcore-architecture-routing-patterns\u002Ferror-handling-global-exceptions","core-architecture-routing-patterns\u002Ferror-handling-global-exceptions\u002Findex",[273,274],{"title":269,"path":270,"stem":271},{"title":275,"path":276,"stem":277,"children":278},"Global Exception Handlers for Consistent API Responses","\u002Fcore-architecture-routing-patterns\u002Ferror-handling-global-exceptions\u002Fglobal-exception-handlers-for-consistent-api-responses","core-architecture-routing-patterns\u002Ferror-handling-global-exceptions\u002Fglobal-exception-handlers-for-consistent-api-responses\u002Findex",[279],{"title":275,"path":276,"stem":277},{"title":281,"path":282,"stem":283,"children":284},"Middleware Implementation in FastAPI","\u002Fcore-architecture-routing-patterns\u002Fmiddleware-implementation","core-architecture-routing-patterns\u002Fmiddleware-implementation\u002Findex",[285,286],{"title":281,"path":282,"stem":283},{"title":287,"path":288,"stem":289,"children":290},"Implementing Custom Middleware for Request Tracing","\u002Fcore-architecture-routing-patterns\u002Fmiddleware-implementation\u002Fimplementing-custom-middleware-for-request-tracing","core-architecture-routing-patterns\u002Fmiddleware-implementation\u002Fimplementing-custom-middleware-for-request-tracing\u002Findex",[291],{"title":287,"path":288,"stem":289},{"title":293,"path":294,"stem":295,"children":296},"Modular Router Organization in FastAPI","\u002Fcore-architecture-routing-patterns\u002Fmodular-router-organization","core-architecture-routing-patterns\u002Fmodular-router-organization\u002Findex",[297,298,304],{"title":293,"path":294,"stem":295},{"title":299,"path":300,"stem":301,"children":302},"APIRouter Prefix vs Sub-Application Mounting in FastAPI","\u002Fcore-architecture-routing-patterns\u002Fmodular-router-organization\u002Fapirouter-prefix-vs-sub-application-mounting","core-architecture-routing-patterns\u002Fmodular-router-organization\u002Fapirouter-prefix-vs-sub-application-mounting\u002Findex",[303],{"title":299,"path":300,"stem":301},{"title":305,"path":306,"stem":307,"children":308},"How to Structure Large FastAPI Projects for Scale","\u002Fcore-architecture-routing-patterns\u002Fmodular-router-organization\u002Fhow-to-structure-large-fastapi-projects-for-scale","core-architecture-routing-patterns\u002Fmodular-router-organization\u002Fhow-to-structure-large-fastapi-projects-for-scale\u002Findex",[309],{"title":305,"path":306,"stem":307},{"id":311,"title":85,"body":312,"description":941,"extension":942,"meta":943,"navigation":528,"path":86,"seo":987,"stem":87,"__hash__":988},"content\u002Fadvanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide\u002Fmodel-config-vs-class-config\u002Findex.md",{"type":313,"value":314,"toc":929},"minimark",[315,319,326,376,384,389,392,396,405,409,414,500,605,609,713,717,799,803,841,845,898,902,925],[316,317,85],"h1",{"id":318},"model_config-vs-class-config-in-pydantic-v2",[320,321,322],"p",{},[323,324,325],"strong",{},"Key takeaways:",[327,328,329,342,358,364,373],"ul",{},[330,331,332,333,337,338,341],"li",{},"Replace the inner ",[334,335,336],"code",{},"class Config"," with ",[334,339,340],{},"model_config = ConfigDict(...)",".",[330,343,344,347,348,351,352,347,355,341],{},[334,345,346],{},"orm_mode"," becomes ",[334,349,350],{},"from_attributes","; ",[334,353,354],{},"allow_population_by_field_name",[334,356,357],{},"populate_by_name",[330,359,360,363],{},[334,361,362],{},"json_encoders"," is replaced by field or model serializers.",[330,365,366,369,370,341],{},[334,367,368],{},"BaseSettings"," uses ",[334,371,372],{},"SettingsConfigDict",[330,374,375],{},"Confirm the configured behavior still applies after the change.",[320,377,378,379,341],{},"This is a focused slice of the ",[380,381,383],"a",{"href":382},"\u002Fadvanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide\u002F","Pydantic V2 Migration Guide",[385,386,388],"h2",{"id":387},"the-problem-this-solves","The Problem This Solves",[320,390,391],{},"Configuration moved from an inner class to a typed dict, and several keys were renamed. A mechanical find-and-replace misses the renames, so a model can appear migrated while silently losing a setting like ORM compatibility. This guide maps the changes precisely.",[385,393,395],{"id":394},"prerequisites","Prerequisites",[327,397,398],{},[330,399,400,401,404],{},"Pydantic v2; ",[334,402,403],{},"pydantic-settings"," for settings models.",[385,406,408],{"id":407},"step-by-step-implementation","Step-by-Step Implementation",[410,411,413],"h3",{"id":412},"_1-the-basic-swap","1. The basic swap",[415,416,421],"pre",{"className":417,"code":418,"language":419,"meta":420,"style":420},"language-python shiki shiki-themes github-light","# Pydantic v1\nclass User(BaseModel):\n    id: int\n    class Config:\n        orm_mode = True\n        allow_population_by_field_name = True\n","python","",[334,422,423,432,453,466,478,490],{"__ignoreMap":420},[424,425,428],"span",{"class":426,"line":427},"line",1,[424,429,431],{"class":430},"sAwPA","# Pydantic v1\n",[424,433,435,439,443,447,450],{"class":426,"line":434},2,[424,436,438],{"class":437},"sD7c4","class",[424,440,442],{"class":441},"s7eDp"," User",[424,444,446],{"class":445},"sgsFI","(",[424,448,449],{"class":441},"BaseModel",[424,451,452],{"class":445},"):\n",[424,454,456,460,463],{"class":426,"line":455},3,[424,457,459],{"class":458},"sYu0t","    id",[424,461,462],{"class":445},": ",[424,464,465],{"class":458},"int\n",[424,467,469,472,475],{"class":426,"line":468},4,[424,470,471],{"class":437},"    class",[424,473,474],{"class":441}," Config",[424,476,477],{"class":445},":\n",[424,479,481,484,487],{"class":426,"line":480},5,[424,482,483],{"class":445},"        orm_mode ",[424,485,486],{"class":437},"=",[424,488,489],{"class":458}," True\n",[424,491,493,496,498],{"class":426,"line":492},6,[424,494,495],{"class":445},"        allow_population_by_field_name ",[424,497,486],{"class":437},[424,499,489],{"class":458},[415,501,503],{"className":417,"code":502,"language":419,"meta":420,"style":420},"# Pydantic v2\nfrom pydantic import BaseModel, ConfigDict\n\n\nclass User(BaseModel):\n    model_config = ConfigDict(\n        from_attributes=True,        # was orm_mode\n        populate_by_name=True,       # was allow_population_by_field_name\n    )\n    id: int\n",[334,504,505,510,524,530,534,546,556,574,590,596],{"__ignoreMap":420},[424,506,507],{"class":426,"line":427},[424,508,509],{"class":430},"# Pydantic v2\n",[424,511,512,515,518,521],{"class":426,"line":434},[424,513,514],{"class":437},"from",[424,516,517],{"class":445}," pydantic ",[424,519,520],{"class":437},"import",[424,522,523],{"class":445}," BaseModel, ConfigDict\n",[424,525,526],{"class":426,"line":455},[424,527,529],{"emptyLinePlaceholder":528},true,"\n",[424,531,532],{"class":426,"line":468},[424,533,529],{"emptyLinePlaceholder":528},[424,535,536,538,540,542,544],{"class":426,"line":480},[424,537,438],{"class":437},[424,539,442],{"class":441},[424,541,446],{"class":445},[424,543,449],{"class":441},[424,545,452],{"class":445},[424,547,548,551,553],{"class":426,"line":492},[424,549,550],{"class":445},"    model_config ",[424,552,486],{"class":437},[424,554,555],{"class":445}," ConfigDict(\n",[424,557,559,563,565,568,571],{"class":426,"line":558},7,[424,560,562],{"class":561},"sqxcx","        from_attributes",[424,564,486],{"class":437},[424,566,567],{"class":458},"True",[424,569,570],{"class":445},",        ",[424,572,573],{"class":430},"# was orm_mode\n",[424,575,577,580,582,584,587],{"class":426,"line":576},8,[424,578,579],{"class":561},"        populate_by_name",[424,581,486],{"class":437},[424,583,567],{"class":458},[424,585,586],{"class":445},",       ",[424,588,589],{"class":430},"# was allow_population_by_field_name\n",[424,591,593],{"class":426,"line":592},9,[424,594,595],{"class":445},"    )\n",[424,597,599,601,603],{"class":426,"line":598},10,[424,600,459],{"class":458},[424,602,462],{"class":445},[424,604,465],{"class":458},[410,606,608],{"id":607},"_2-replacing-json_encoders","2. Replacing json_encoders",[415,610,612],{"className":417,"code":611,"language":419,"meta":420,"style":420},"from datetime import datetime\n\nfrom pydantic import BaseModel, field_serializer\n\n\nclass Event(BaseModel):\n    at: datetime\n\n    @field_serializer(\"at\")          # Replaces v1 Config.json_encoders.\n    def ser_at(self, value: datetime) -> str:\n        return value.isoformat()\n",[334,613,614,626,630,641,645,649,662,667,671,688,704],{"__ignoreMap":420},[424,615,616,618,621,623],{"class":426,"line":427},[424,617,514],{"class":437},[424,619,620],{"class":445}," datetime ",[424,622,520],{"class":437},[424,624,625],{"class":445}," datetime\n",[424,627,628],{"class":426,"line":434},[424,629,529],{"emptyLinePlaceholder":528},[424,631,632,634,636,638],{"class":426,"line":455},[424,633,514],{"class":437},[424,635,517],{"class":445},[424,637,520],{"class":437},[424,639,640],{"class":445}," BaseModel, field_serializer\n",[424,642,643],{"class":426,"line":468},[424,644,529],{"emptyLinePlaceholder":528},[424,646,647],{"class":426,"line":480},[424,648,529],{"emptyLinePlaceholder":528},[424,650,651,653,656,658,660],{"class":426,"line":492},[424,652,438],{"class":437},[424,654,655],{"class":441}," Event",[424,657,446],{"class":445},[424,659,449],{"class":441},[424,661,452],{"class":445},[424,663,664],{"class":426,"line":558},[424,665,666],{"class":445},"    at: datetime\n",[424,668,669],{"class":426,"line":576},[424,670,529],{"emptyLinePlaceholder":528},[424,672,673,676,678,682,685],{"class":426,"line":592},[424,674,675],{"class":441},"    @field_serializer",[424,677,446],{"class":445},[424,679,681],{"class":680},"sYBdl","\"at\"",[424,683,684],{"class":445},")          ",[424,686,687],{"class":430},"# Replaces v1 Config.json_encoders.\n",[424,689,690,693,696,699,702],{"class":426,"line":598},[424,691,692],{"class":437},"    def",[424,694,695],{"class":441}," ser_at",[424,697,698],{"class":445},"(self, value: datetime) -> ",[424,700,701],{"class":458},"str",[424,703,477],{"class":445},[424,705,707,710],{"class":426,"line":706},11,[424,708,709],{"class":437},"        return",[424,711,712],{"class":445}," value.isoformat()\n",[410,714,716],{"id":715},"_3-settings-models","3. Settings models",[415,718,720],{"className":417,"code":719,"language":419,"meta":420,"style":420},"from pydantic_settings import BaseSettings, SettingsConfigDict\n\n\nclass Settings(BaseSettings):\n    # SettingsConfigDict for BaseSettings; ConfigDict for plain models.\n    model_config = SettingsConfigDict(env_prefix=\"APP_\", extra=\"forbid\")\n    database_url: str\n",[334,721,722,734,738,742,755,760,791],{"__ignoreMap":420},[424,723,724,726,729,731],{"class":426,"line":427},[424,725,514],{"class":437},[424,727,728],{"class":445}," pydantic_settings ",[424,730,520],{"class":437},[424,732,733],{"class":445}," BaseSettings, SettingsConfigDict\n",[424,735,736],{"class":426,"line":434},[424,737,529],{"emptyLinePlaceholder":528},[424,739,740],{"class":426,"line":455},[424,741,529],{"emptyLinePlaceholder":528},[424,743,744,746,749,751,753],{"class":426,"line":468},[424,745,438],{"class":437},[424,747,748],{"class":441}," Settings",[424,750,446],{"class":445},[424,752,368],{"class":441},[424,754,452],{"class":445},[424,756,757],{"class":426,"line":480},[424,758,759],{"class":430},"    # SettingsConfigDict for BaseSettings; ConfigDict for plain models.\n",[424,761,762,764,766,769,772,774,777,780,783,785,788],{"class":426,"line":492},[424,763,550],{"class":445},[424,765,486],{"class":437},[424,767,768],{"class":445}," SettingsConfigDict(",[424,770,771],{"class":561},"env_prefix",[424,773,486],{"class":437},[424,775,776],{"class":680},"\"APP_\"",[424,778,779],{"class":445},", ",[424,781,782],{"class":561},"extra",[424,784,486],{"class":437},[424,786,787],{"class":680},"\"forbid\"",[424,789,790],{"class":445},")\n",[424,792,793,796],{"class":426,"line":558},[424,794,795],{"class":445},"    database_url: ",[424,797,798],{"class":458},"str\n",[385,800,802],{"id":801},"edge-cases-and-gotchas","Edge Cases and Gotchas",[327,804,805,817,828],{},[330,806,807,810,811,779,813,779,815,341],{},[323,808,809],{},"Silent key drops."," A renamed key left under the old name is simply ignored; grep for ",[334,812,346],{},[334,814,354],{},[334,816,362],{},[330,818,819,824,825,827],{},[323,820,821,823],{},[334,822,782],{}," behavior."," v2's defaults around extra fields differ; set ",[334,826,782],{}," explicitly where it matters.",[330,829,830,833,834,836,837,840],{},[323,831,832],{},"Mixed styles."," Do not leave some models on ",[334,835,336],{}," and others on ",[334,838,839],{},"model_config","; standardize.",[385,842,844],{"id":843},"verification","Verification",[415,846,848],{"className":417,"code":847,"language":419,"meta":420,"style":420},"def test_from_attributes_works():\n    class Row:\n        id = 7\n    assert User.model_validate(Row()).id == 7   # from_attributes in effect.\n",[334,849,850,861,870,881],{"__ignoreMap":420},[424,851,852,855,858],{"class":426,"line":427},[424,853,854],{"class":437},"def",[424,856,857],{"class":441}," test_from_attributes_works",[424,859,860],{"class":445},"():\n",[424,862,863,865,868],{"class":426,"line":434},[424,864,471],{"class":437},[424,866,867],{"class":441}," Row",[424,869,477],{"class":445},[424,871,872,875,878],{"class":426,"line":455},[424,873,874],{"class":458},"        id",[424,876,877],{"class":437}," =",[424,879,880],{"class":458}," 7\n",[424,882,883,886,889,892,895],{"class":426,"line":468},[424,884,885],{"class":437},"    assert",[424,887,888],{"class":445}," User.model_validate(Row()).id ",[424,890,891],{"class":437},"==",[424,893,894],{"class":458}," 7",[424,896,897],{"class":430},"   # from_attributes in effect.\n",[385,899,901],{"id":900},"related-reading","Related Reading",[327,903,904,912],{},[330,905,906,909,910,341],{},[323,907,908],{},"Up to the topic:"," ",[380,911,383],{"href":382},[330,913,914,909,917,921,922,341],{},[323,915,916],{},"Related guides:",[380,918,920],{"href":919},"\u002Fadvanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide\u002Fmigrate-validator-to-field-validator\u002F","Migrate @validator to @field_validator"," and ",[380,923,239],{"href":924},"\u002Fcore-architecture-routing-patterns\u002Fconfiguration-management\u002Fmanaging-environment-variables-with-pydantic-settings\u002F",[926,927,928],"style",{},"html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sqxcx, html code.shiki .sqxcx{--shiki-default:#E36209}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}",{"title":420,"searchDepth":434,"depth":434,"links":930},[931,932,933,938,939,940],{"id":387,"depth":434,"text":388},{"id":394,"depth":434,"text":395},{"id":407,"depth":434,"text":408,"children":934},[935,936,937],{"id":412,"depth":455,"text":413},{"id":607,"depth":455,"text":608},{"id":715,"depth":455,"text":716},{"id":801,"depth":434,"text":802},{"id":843,"depth":434,"text":844},{"id":900,"depth":434,"text":901},"Migrate Pydantic v1 class Config to v2 model_config with ConfigDict: renamed keys like orm_mode to from_attributes, allow_population_by_field_name, and settings differences.","md",{"slug":944,"type":945,"breadcrumb":946,"datePublished":957,"dateModified":958,"howto":959,"faq":977},"model-config-vs-class-config","long_tail",[947,950,953,954],{"label":948,"path":949},"Home","\u002F",{"label":951,"path":952},"Advanced Pydantic Validation & Serialization","\u002Fadvanced-pydantic-validation-serialization\u002F",{"label":383,"path":382},{"label":955,"path":956},"model_config vs class Config","\u002Fadvanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide\u002Fmodel-config-vs-class-config\u002F","2026-03-02","2026-06-18",{"name":960,"steps":961},"Migrate class Config to model_config in Pydantic v2",[962,965,968,971,974],{"name":963,"text":964},"Replace the inner class","Swap the inner class Config for model_config = ConfigDict(...).",{"name":966,"text":967},"Rename moved keys","Map orm_mode to from_attributes and allow_population_by_field_name to populate_by_name.",{"name":969,"text":970},"Move json_encoders","Replace json_encoders with field serializers or model_serializer.",{"name":972,"text":973},"Apply to settings","Use SettingsConfigDict for BaseSettings subclasses.",{"name":975,"text":976},"Verify config takes effect","Test that the configured behavior such as from_attributes still works.",[978,981,984],{"q":979,"a":980},"What replaces class Config in Pydantic v2?","A class attribute model_config assigned a ConfigDict, for example model_config = ConfigDict(from_attributes=True). The inner class Config style still works in many cases for backward compatibility, but the supported v2 form is the ConfigDict attribute, and several keys were renamed in the move.",{"q":982,"a":983},"What did orm_mode become in v2?","orm_mode is now from_attributes. Setting model_config = ConfigDict(from_attributes=True) lets a model validate from arbitrary objects with matching attributes, such as ORM rows. The behavior is the same; only the key name changed.",{"q":985,"a":986},"How do I replace json_encoders from v1 config?","v2 deprecates json_encoders in favor of serialization hooks: use a field_serializer for a single field or a model_serializer for whole-model custom output. These run on the Rust core and integrate with model_dump and model_dump_json, unlike the v1 encoder dict.",{"title":85,"description":941},"TIlOio_AGj09nEyUw7e4b5vrIbITHCCz0E9cWTukfwE",[990,990],null,1781809863211]