mirror of
https://github.com/davidhalter/django-stubs.git
synced 2025-12-10 22:11:54 +08:00
Fix incorrect instance arg for BaseInlineFormSet.__init__ (#928)
* Fix BaseInlineFormSet generic to retain parent model class info * Add in test for generic formset improvements
This commit is contained in:
@@ -296,7 +296,7 @@ _ParentModelT = TypeVar("_ParentModelT", bound=Model)
|
||||
class InlineModelAdmin(Generic[_ChildModelT, _ParentModelT], BaseModelAdmin[_ChildModelT]):
|
||||
model: Type[_ChildModelT] = ...
|
||||
fk_name: Optional[str] = ...
|
||||
formset: Type[BaseInlineFormSet[_ChildModelT, forms.ModelForm[_ChildModelT]]] = ...
|
||||
formset: Type[BaseInlineFormSet[_ChildModelT, _ParentModelT, forms.ModelForm[_ChildModelT]]] = ...
|
||||
extra: int = ...
|
||||
min_num: Optional[int] = ...
|
||||
max_num: Optional[int] = ...
|
||||
@@ -318,7 +318,7 @@ class InlineModelAdmin(Generic[_ChildModelT, _ParentModelT], BaseModelAdmin[_Chi
|
||||
def get_max_num(self, request: HttpRequest, obj: Optional[_ParentModelT] = ..., **kwargs: Any) -> Optional[int]: ...
|
||||
def get_formset(
|
||||
self, request: HttpRequest, obj: Optional[_ParentModelT] = ..., **kwargs: Any
|
||||
) -> Type[BaseInlineFormSet[_ChildModelT, forms.ModelForm[_ChildModelT]]]: ...
|
||||
) -> Type[BaseInlineFormSet[_ChildModelT, _ParentModelT, forms.ModelForm[_ChildModelT]]]: ...
|
||||
def get_queryset(self, request: HttpRequest) -> QuerySet[_ChildModelT]: ...
|
||||
def has_add_permission(self, request: HttpRequest, obj: Optional[_ParentModelT]) -> bool: ... # type: ignore
|
||||
def has_change_permission(self, request: HttpRequest, obj: Optional[_ParentModelT] = ...) -> bool: ... # type: ignore
|
||||
|
||||
@@ -50,6 +50,7 @@ _ErrorMessages = Dict[str, Dict[str, str]]
|
||||
_FormFieldCallback = Callable[[models.Field], Field]
|
||||
|
||||
_M = TypeVar("_M", bound=Model)
|
||||
_ParentM = TypeVar("_ParentM", bound=Model)
|
||||
|
||||
def construct_instance(
|
||||
form: BaseForm, instance: _M, fields: Optional[Container[str]] = ..., exclude: Optional[Container[str]] = ...
|
||||
@@ -187,8 +188,8 @@ def modelformset_factory(
|
||||
can_delete_extra: bool = ...,
|
||||
) -> Type[BaseModelFormSet[_M, _ModelFormT]]: ...
|
||||
|
||||
class BaseInlineFormSet(BaseModelFormSet[_M, _ModelFormT]):
|
||||
instance: Model = ...
|
||||
class BaseInlineFormSet(Generic[_M, _ParentM, _ModelFormT], BaseModelFormSet[_M, _ModelFormT]):
|
||||
instance: _ParentM
|
||||
save_as_new: bool = ...
|
||||
unique_fields: Collection[str] = ...
|
||||
fk: ForeignKey # set by inlineformset_set
|
||||
@@ -196,7 +197,7 @@ class BaseInlineFormSet(BaseModelFormSet[_M, _ModelFormT]):
|
||||
self,
|
||||
data: Optional[_DataT] = ...,
|
||||
files: Optional[_FilesT] = ...,
|
||||
instance: Optional[_M] = ...,
|
||||
instance: Optional[_ParentM] = ...,
|
||||
save_as_new: bool = ...,
|
||||
prefix: Optional[str] = ...,
|
||||
queryset: Optional[QuerySet[_M]] = ...,
|
||||
@@ -210,7 +211,7 @@ class BaseInlineFormSet(BaseModelFormSet[_M, _ModelFormT]):
|
||||
def get_unique_error_message(self, unique_check: Sequence[str]) -> str: ...
|
||||
|
||||
def inlineformset_factory(
|
||||
parent_model: Type[Model],
|
||||
parent_model: Type[_ParentM],
|
||||
model: Type[_M],
|
||||
form: Type[_ModelFormT] = ...,
|
||||
formset: Type[BaseInlineFormSet] = ...,
|
||||
@@ -233,7 +234,7 @@ def inlineformset_factory(
|
||||
field_classes: Optional[Mapping[str, Type[Field]]] = ...,
|
||||
absolute_max: Optional[int] = ...,
|
||||
can_delete_extra: bool = ...,
|
||||
) -> Type[BaseInlineFormSet[_M, _ModelFormT]]: ...
|
||||
) -> Type[BaseInlineFormSet[_M, _ParentM, _ModelFormT]]: ...
|
||||
|
||||
class InlineForeignKeyField(Field):
|
||||
disabled: bool
|
||||
|
||||
21
tests/typecheck/test_formsets.yml
Normal file
21
tests/typecheck/test_formsets.yml
Normal file
@@ -0,0 +1,21 @@
|
||||
- case: inlineformset_factory
|
||||
main: |
|
||||
from typing import Any, Type
|
||||
from django import forms
|
||||
from myapp.models import Article, Category
|
||||
ArticleFS: Type[forms.BaseInlineFormSet[Article, Category, Any]] = forms.inlineformset_factory(Category, Article)
|
||||
ArticleFS(instance=Article()) # E: Argument "instance" to "BaseInlineFormSet" has incompatible type "Article"; expected "Optional[Category]"
|
||||
fs = ArticleFS(instance=Category())
|
||||
reveal_type(fs.instance) # N: Revealed type is "myapp.models.Category*"
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
|
||||
class Article(models.Model):
|
||||
pass
|
||||
class Category(models.Model):
|
||||
pass
|
||||
Reference in New Issue
Block a user