The stub file for serializers.ModelSerializer
shows that it inherits from a generic base class BaseSerializer
. This means that ModelSerializer
is also generic:
# (Imports excluded for the sake of brevity)
_MT = TypeVar("_MT", bound=Model) # Model Type
# <-- snip -->
class ModelSerializer(Serializer, BaseSerializer[_MT]):
serializer_field_mapping: Dict[Type[models.Field], Type[Field]] = ...
serializer_related_field: Type[RelatedField] = ...
serializer_related_to_field: Type[RelatedField] = ...
serializer_url_field: Type[RelatedField] = ...
serializer_choice_field: Type[Field] = ...
url_field_name: Optional[str] = ...
instance: Optional[Union[_MT, Sequence[_MT]]] # type: ignore[override]
class Meta:
model: Type[_MT] # type: ignore
fields: Union[Sequence[str], Literal["__all__"]]
read_only_fields: Optional[Sequence[str]]
exclude: Optional[Sequence[str]]
depth: Optional[int]
extra_kwargs: Dict[str, Dict[str, Any]] # type: ignore[override]
def __init__(
self,
instance: Union[None, _MT, Sequence[_MT], QuerySet[_MT], Manager[_MT]] = ...,
data: Any = ...,
partial: bool = ...,
many: bool = ...,
context: Dict[str, Any] = ...,
read_only: bool = ...,
write_only: bool = ...,
required: bool = ...,
default: Union[Union[_MT, Sequence[_MT]], Callable[[], Union[_MT, Sequence[_MT]]]] = ...,
initial: Union[Union[_MT, Sequence[_MT]], Callable[[], Union[_MT, Sequence[_MT]]]] = ...,
source: str = ...,
label: str = ...,
help_text: str = ...,
style: Dict[str, Any] = ...,
error_messages: Dict[str, str] = ...,
validators: Optional[Sequence[Validator[_MT]]] = ...,
allow_null: bool = ...,
allow_empty: bool = ...,
): ...
def update(self, instance: _MT, validated_data: Any) -> _MT: ... # type: ignore[override]
def create(self, validated_data: Any) -> _MT: ... # type: ignore[override]
def save(self, **kwargs: Any) -> _MT: ... # type: ignore[override]
def to_representation(self, instance: _MT) -> Any: ... # type: ignore[override]
def get_field_names(self, declared_fields: Mapping[str, Field], info: FieldInfo) -> List[str]: ...
def get_default_field_names(self, declared_fields: Mapping[str, Field], model_info: FieldInfo) -> List[str]: ...
def build_field(
self, field_name: str, info: FieldInfo, model_class: _MT, nested_depth: int
) -> Tuple[Field, Dict[str, Any]]: ...
def build_standard_field(
self, field_name: str, model_field: Type[models.Field]
) -> Tuple[Field, Dict[str, Any]]: ...
def build_relational_field(
self, field_name: str, relation_info: RelationInfo
) -> Tuple[Type[Field], Dict[str, Any]]: ...
def build_nested_field(
self, field_name: str, relation_info: RelationInfo, nested_depth: int
) -> Tuple[Field, Dict[str, Any]]: ...
def build_property_field(self, field_name: str, model_class: _MT) -> Tuple[Field, Dict[str, Any]]: ...
def build_url_field(self, field_name: str, model_class: _MT) -> Tuple[Field, Dict[str, Any]]: ...
def build_unknown_field(self, field_name: str, model_class: _MT) -> NoReturn: ...
def include_extra_kwargs(
self, kwargs: MutableMapping[str, Any], extra_kwargs: MutableMapping[str, Any]
) -> MutableMapping[str, Any]: ...
def get_extra_kwargs(self) -> Dict[str, Any]: ...
def get_uniqueness_extra_kwargs(
self, field_names: Iterable[str], declared_fields: Mapping[str, Field], extra_kwargs: Dict[str, Any]
) -> Tuple[Dict[str, Any], Dict[str, HiddenField]]: ...
def _get_model_fields(
self, field_names: Iterable[str], declared_fields: Mapping[str, Field], extra_kwargs: MutableMapping[str, Any]
) -> Dict[str, models.Field]: ...
def get_unique_together_validators(self) -> List[UniqueTogetherValidator]: ...
def get_unique_for_date_validators(self) -> List[BaseUniqueForValidator]: ...
When run with the --disallow-any-generics option, MyPy will complain if you inherit from an unparameterised generic, as it is unclear whether you want your inherited class to also be considered generic, or whether you want it to be considered a more concrete version of the base class.
As you have the line model = Animal
in the Meta
class in your derived class, and the stub file annotates ModelSerializer.Meta.model
as being of type Type[_MT]
, my guess is that you do not want want your AnimalSerializer
class to be generic, and instead want it to be specific to an Animal
class that is a subclass of Model
. As such, you need to rewrite your AnimalSerializer
class like this:
class AnimalSerializer(serializers.ModelSerializer[Animal]):
class Meta:
model = Animal
fields = "__all__"