Skip to content

🎨 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:

custom_templates/
└── pydantic/
    └── BaseModel.jinja2

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

datamodel-codegen --input person.json --output person.py --custom-template-dir custom_templates

✨ 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