Skip to content

Q: Is there a recommended way for type hinting Historical[Model]? #1236

Open
@Kangaroux

Description

@Kangaroux

Was looking for a way to add type hinting so I could reference the historical model. This is what I came up with. Just curious if anyone else has a solution they use.

I have this defined in a shared part of the code:

from datetime import datetime
from typing import TYPE_CHECKING, Any, Generic, Optional, TypeVar

from simple_history.models import ModelDelta
from typing_extensions import Self


if TYPE_CHECKING:
    from users.models import User

    T = TypeVar("T")

    class HistoricalModel(Generic[T]):
        history_change_reason: str
        history_date: datetime
        history_id: Any
        history_object: Any
        history_relation: Any
        history_type: str
        history_user: Optional[User]
        history_user_id: Any
        instance_type: type[T]
        instance: T

        def diff_against(
            self,
            old_history: "Self",
            excluded_fields: Optional[list[str]] = None,
            included_fields: Optional[list[str]] = None,
        ) -> ModelDelta:
            ...

        def get_default_history_user(self) -> Optional[User]:
            ...

        def next_record(self) -> Optional[T]:
            ...

        def prev_record(self) -> Optional[T]:
            ...

        def revert_url(self) -> str:
            ...

And below each model I define the historical model. I had to add a type ignore because mypy was complaining about incompatible metaclasses.

class MyModel(models.Model):
    ...


if TYPE_CHECKING:
    from common.utils import HistoricalModel

    class HistoricalMyModel(  # type: ignore
        HistoricalModel[MyModel],
        MyModel,
    ):
        ...

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions