datamodel-code-generator icon indicating copy to clipboard operation
datamodel-code-generator copied to clipboard

I use --extra-fields forbid and it doesn't work

Open Airpy opened this issue 5 months ago • 1 comments

my datamodel-code-generator version is: 0.31.0

my json:

{
    "code": 0,
    "message": "success",
    "data": {
        "user_id": 12345,
        "username": "test_user",
        "email": "[email protected]",
        "permissions": ["read", "write", "delete"],
        "profile": {"level": 5, "score": 85, "tags": ["active", "premium"]},
        "history": [
            {"action": "login", "timestamp": "2024-01-01"},
            {"action": "update", "timestamp": "2024-01-02", "details": {"old_value": "100", "new_value": "200"}}
        ]
    }
}

my command line:

datamodel-codegen --input test.json --input-file-type json --output test.py --output-model-type pydantic_v2.BaseModel --class-name Test --use-annotated --field-constraints --snake-case-field --allow-population-by-field-name --extra-fields forbid --use-default --strip-default-none --use-schema-description --use-field-description --reuse-model --use-default-kwarg --target-python-version 3.12 --encoding utf-8 --use-union-operator --use-standard-collections --disable-timestamp --formatters ruff-format ruff-check --extra-fields forbid

generate result is:

# generated by datamodel-codegen:
#   filename:  test.json

from __future__ import annotations

from pydantic import BaseModel, ConfigDict


class Profile(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
    )
    level: int
    score: int
    tags: list[str]


class Details(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
    )
    old_value: str
    new_value: str


class HistoryItem(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
    )
    action: str
    timestamp: str
    details: Details | None


class Data(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
    )
    user_id: int
    username: str
    email: str
    permissions: list[str]
    profile: Profile
    history: list[HistoryItem]


class Test(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
    )
    code: int
    message: str
    data: Data

Shouldn't this be the correct result?

# generated by datamodel-codegen:
#   filename:  test.json

from __future__ import annotations

from pydantic import BaseModel, ConfigDict


class Profile(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
        extra="forbid",
    )
    level: int
    score: int
    tags: list[str]


class Details(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
        extra="forbid",
    )
    old_value: str
    new_value: str


class HistoryItem(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
        extra="forbid",
    )
    action: str
    timestamp: str
    details: Details | None


class Data(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
        extra="forbid",
    )
    user_id: int
    username: str
    email: str
    permissions: list[str]
    profile: Profile
    history: list[HistoryItem]


class Test(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
        extra="forbid",
    )
    code: int
    message: str
    data: Data

Airpy avatar Jun 16 '25 00:06 Airpy

@Airpy, I've opened a PR which I believe fixes this. Apologies for the oversight.

cosmo-grant avatar Jun 16 '25 16:06 cosmo-grant