Inheritance from models fields
I've got the following snippet
from django.db import models
class PhoneField(models.CharField):
"""Phone field based on CharField with validation."""
def __init__(self, *args, **kwargs) -> None:
"""Init."""
options = {
"max_length": 30,
"validators": (must_be_valid_number, ),
}
options.update(kwargs)
super().__init__(*args, **options)
And there are two problems:
-
First -
models.py:3 error: Missing type parameters for generic type "CharField" -
And second
models.py:13: error: Argument 2 to "__init__" of "CharField" has incompatible type "**Dict[str, object]"; expected "Union[str, bytes, None]"
models.py:13: error: Argument 2 to "__init__" of "CharField" has incompatible type "**Dict[str, object]"; expected "Optional[str]"
models.py:13: error: Argument 2 to "__init__" of "CharField" has incompatible type "**Dict[str, object]"; expected "bool"
models.py:13: error: Argument 2 to "__init__" of "CharField" has incompatible type "**Dict[str, object]"; expected "Optional[int]"
models.py:13: error: Argument 2 to "__init__" of "CharField" has incompatible type "**Dict[str, object]"; expected "Optional[Iterable[Union[Tuple[Any, Any], Tuple[str, Iterable[Tuple[Any, Any]]]]]]"
models.py:13: error: Argument 2 to "__init__" of "CharField" has incompatible type "**Dict[str, object]"; expected "str"
models.py:13: error: Argument 2 to "__init__" of "CharField" has incompatible type "**Dict[str, object]"; expected "Iterable[Callable[..., None]]"
models.py:13: error: Argument 2 to "__init__" of "CharField" has incompatible type "**Dict[str, object]"; expected "Optional[Dict[str, Any]]"
How can I annotate generic CharField?
And how can I pass kwargs to super?
Can you try completing the annotation on your init definition?
def __init__(self, *args: Any, **kwargs: Any) -> None:
and type your options variable:
options: Dict[str, Any] = {
I did and incompatible type "**Dict[str, object]" errors are gone.
But I still get models.py:3 error: Missing type parameters for generic type "CharField" error.
I also have the same error: Missing type parameters for generic type "DateTimeField" when subclassing a Django DateTime field.
class AutoDateTimeField(models.DateTimeField):
"""
A custom model field based on :class:`django.db.models.DateTimeField` that
updates itself to `django.utils.timezone.now()` upon updating it's model.
"""
def pre_save(self, model_instance, add) -> datetime:
"""
Hook to timestamp model before it's saved.
"""
return timezone.now()
Any workaround?
All fields are generic with kind of 2: https://github.com/typeddjango/django-stubs/blob/master/django-stubs/db/models/fields/init.pyi#L45
You can try to do something like this:
from typing import TypeVar
# __set__ value type
_ST = TypeVar("_ST")
# __get__ return type
_GT = TypeVar("_GT")
class AutoDateTimeField(models.DateTimeField[_ST, _GT]):
...
@sobolevn doesn't work, it results in:
class AutoDateTimeField(models.DateTimeField[_ST, _GT]):
TypeError: 'type' object is not subscriptable
That because of https://github.com/django/django/pull/12405
Sadly, I don't have any ideas on how to fix it except # type: ignore
That because of django/django#12405
Sadly, I don't have any ideas on how to fix it except
# type: ignore
Just for reference: this can be fixed now with django_stubs_ext:
import django_stubs_ext
django_stubs_ext.monkeypatch()
I encountered this error because I was typing something that was already implicitly typed correctly:
- name: models.CharField = models.CharField(max_length=100, primary_key=True)
+ name = models.CharField(max_length=100, primary_key=True)