🎨 Custom Templates¶
One of the powerful features of datamodel-code-generator is the ability to use custom templates with the --custom-template-dir option. This allows you to provide a directory containing Jinja2 templates for customizing the generated code.
🚀 Usage¶
Pass the directory path containing your custom templates:
datamodel-codegen --input {your_input_file} --output {your_output_file} --custom-template-dir {your_custom_template_directory}
📝 Example¶
Let's say you want to generate a custom Python data model from a JSON Schema file called person.json. You want the generated data model to include a custom comment at the top of the file.
1️⃣ Create the template directory¶
Create a directory structure matching the output model type:
2️⃣ Create the template¶
custom_templates/pydantic/BaseModel.jinja2
# This is a custom comment generated with custom_template!!
class {{ class_name }}({{ base_class }}):
{%- for field in fields %}
{{ field.name }}: {{ field.type_hint }}
{%- endfor -%}
This custom template includes the custom comment at the top and replicates the default rendering behavior of the BaseModel.jinja2 template.
3️⃣ Run the generator¶
✨ Generated Output¶
person.py
# generated by datamodel-codegen:
# filename: person.json
# timestamp: 2023-04-09T05:36:24+00:00
from __future__ import annotations
from typing import Optional
from pydantic import BaseModel
# This is a custom comment generated with custom_template!!
class Model(BaseModel):
name: Optional[str]
age: Optional[int]
📚 Template Reference¶
You can create more complex custom templates by copying the default templates. Use them as a reference for understanding the structure and available variables, and customize the code generation process according to your specific requirements.
🔧 Schema Extensions¶
OpenAPI and JSON Schema allow custom extension fields prefixed with x-. These schema extensions are automatically passed to templates via the extensions variable, enabling dynamic code generation based on your custom schema metadata.
Example: Database Model Configuration¶
Suppose you want to add a __collection__ class attribute based on a custom x-database-model extension in your OpenAPI schema:
api.yaml
openapi: "3.0.0"
info:
version: 1.0.0
title: My API
paths: {}
components:
schemas:
User:
type: object
x-database-model:
collection: users
indexes:
- email
properties:
id:
type: string
email:
type: string
required:
- id
- email
custom_templates/pydantic_v2/BaseModel.jinja2
class {{ class_name }}({{ base_class }}):
{%- if extensions is defined and extensions.get('x-database-model') %}
__collection__ = "{{ extensions['x-database-model']['collection'] }}"
{%- endif %}
{%- for field in fields %}
{{ field.name }}: {{ field.type_hint }}
{%- endfor %}
Run the generator
datamodel-codegen --input api.yaml --output models.py \
--custom-template-dir custom_templates \
--output-model-type pydantic_v2.BaseModel
Generated Output
from __future__ import annotations
from pydantic import BaseModel
class User(BaseModel):
__collection__ = "users"
id: str
email: str
Available Extensions¶
Any field starting with x- in your schema will be available in the extensions dictionary:
| Schema Field | Template Access |
|---|---|
x-database-model |
extensions['x-database-model'] |
x-custom-flag |
extensions['x-custom-flag'] |
x-my-extension |
extensions['x-my-extension'] |
Use Cases¶
- Database mapping: Add collection names, indexes, or ORM configurations
- Validation rules: Include custom validation logic based on schema metadata
- Documentation: Generate custom docstrings or comments from schema extensions
- Framework integration: Add framework-specific decorators or attributes
📖 See Also¶
- 🖥️ CLI Reference:
--custom-template-dir- Detailed CLI option documentation - 📊 CLI Reference:
--extra-template-data- Pass custom variables to templates