mirror of
https://github.com/davidhalter/django-stubs.git
synced 2025-12-10 22:11:54 +08:00
make FormMixin generic to allow proper typing for LoginView (#515)
closes #514
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
from typing import Any, Optional, Set
|
from typing import Any, Optional, Set
|
||||||
|
|
||||||
from django.contrib.auth.base_user import AbstractBaseUser
|
from django.contrib.auth.base_user import AbstractBaseUser
|
||||||
|
from django.contrib.auth.forms import AuthenticationForm
|
||||||
from django.core.handlers.wsgi import WSGIRequest
|
from django.core.handlers.wsgi import WSGIRequest
|
||||||
from django.http.request import HttpRequest
|
from django.http.request import HttpRequest
|
||||||
from django.http.response import HttpResponseRedirect
|
from django.http.response import HttpResponseRedirect
|
||||||
@@ -14,7 +15,7 @@ class SuccessURLAllowedHostsMixin:
|
|||||||
success_url_allowed_hosts: Any = ...
|
success_url_allowed_hosts: Any = ...
|
||||||
def get_success_url_allowed_hosts(self) -> Set[str]: ...
|
def get_success_url_allowed_hosts(self) -> Set[str]: ...
|
||||||
|
|
||||||
class LoginView(SuccessURLAllowedHostsMixin, FormView):
|
class LoginView(SuccessURLAllowedHostsMixin, FormView[AuthenticationForm]):
|
||||||
authentication_form: Any = ...
|
authentication_form: Any = ...
|
||||||
redirect_field_name: Any = ...
|
redirect_field_name: Any = ...
|
||||||
redirect_authenticated_user: bool = ...
|
redirect_authenticated_user: bool = ...
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from typing import Any, Callable, Dict, Optional, Sequence, Type, Union
|
from typing import Any, Callable, Dict, Generic, Optional, Sequence, Type, TypeVar, Union
|
||||||
|
|
||||||
from django.forms.forms import BaseForm
|
from django.forms.forms import BaseForm
|
||||||
from django.forms.models import BaseModelForm
|
from django.forms.models import BaseModelForm
|
||||||
@@ -8,6 +8,8 @@ from typing_extensions import Literal
|
|||||||
|
|
||||||
from django.http import HttpRequest, HttpResponse
|
from django.http import HttpRequest, HttpResponse
|
||||||
|
|
||||||
|
_FormT = TypeVar('_FormT', bound=BaseForm)
|
||||||
|
|
||||||
class AbstractFormMixin(ContextMixin):
|
class AbstractFormMixin(ContextMixin):
|
||||||
initial: Dict[str, Any] = ...
|
initial: Dict[str, Any] = ...
|
||||||
form_class: Optional[Type[BaseForm]] = ...
|
form_class: Optional[Type[BaseForm]] = ...
|
||||||
@@ -18,11 +20,11 @@ class AbstractFormMixin(ContextMixin):
|
|||||||
def get_form_kwargs(self) -> Dict[str, Any]: ...
|
def get_form_kwargs(self) -> Dict[str, Any]: ...
|
||||||
def get_success_url(self) -> str: ...
|
def get_success_url(self) -> str: ...
|
||||||
|
|
||||||
class FormMixin(AbstractFormMixin):
|
class FormMixin(Generic[_FormT], AbstractFormMixin):
|
||||||
def get_form_class(self) -> Type[BaseForm]: ...
|
def get_form_class(self) -> Type[_FormT]: ...
|
||||||
def get_form(self, form_class: Optional[Type[BaseForm]] = ...) -> BaseForm: ...
|
def get_form(self, form_class: Optional[Type[_FormT]] = ...) -> BaseForm: ...
|
||||||
def form_valid(self, form: BaseForm) -> HttpResponse: ...
|
def form_valid(self, form: _FormT) -> HttpResponse: ...
|
||||||
def form_invalid(self, form: BaseForm) -> HttpResponse: ...
|
def form_invalid(self, form: _FormT) -> HttpResponse: ...
|
||||||
|
|
||||||
class ModelFormMixin(AbstractFormMixin, SingleObjectMixin):
|
class ModelFormMixin(AbstractFormMixin, SingleObjectMixin):
|
||||||
fields: Optional[Union[Sequence[str], Literal["__all__"]]] = ...
|
fields: Optional[Union[Sequence[str], Literal["__all__"]]] = ...
|
||||||
@@ -36,8 +38,8 @@ class ProcessFormView(View):
|
|||||||
def post(self, request: HttpRequest, *args: str, **kwargs: Any) -> HttpResponse: ...
|
def post(self, request: HttpRequest, *args: str, **kwargs: Any) -> HttpResponse: ...
|
||||||
def put(self, *args: str, **kwargs: Any) -> HttpResponse: ...
|
def put(self, *args: str, **kwargs: Any) -> HttpResponse: ...
|
||||||
|
|
||||||
class BaseFormView(FormMixin, ProcessFormView): ...
|
class BaseFormView(FormMixin[_FormT], ProcessFormView): ...
|
||||||
class FormView(TemplateResponseMixin, BaseFormView): ...
|
class FormView(TemplateResponseMixin, BaseFormView[_FormT]): ...
|
||||||
class BaseCreateView(ModelFormMixin, ProcessFormView): ...
|
class BaseCreateView(ModelFormMixin, ProcessFormView): ...
|
||||||
class CreateView(SingleObjectTemplateResponseMixin, BaseCreateView): ...
|
class CreateView(SingleObjectTemplateResponseMixin, BaseCreateView): ...
|
||||||
class BaseUpdateView(ModelFormMixin, ProcessFormView): ...
|
class BaseUpdateView(ModelFormMixin, ProcessFormView): ...
|
||||||
|
|||||||
12
tests/typecheck/test_views.yml
Normal file
12
tests/typecheck/test_views.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
- case: login_form_form_valid_typechecks
|
||||||
|
main: |
|
||||||
|
from django.contrib.auth.views import LoginView
|
||||||
|
from django.contrib.auth import login as auth_login
|
||||||
|
from django.http import HttpResponseRedirect
|
||||||
|
from django.contrib.auth.forms import AuthenticationForm
|
||||||
|
|
||||||
|
class MyLoginView(LoginView):
|
||||||
|
def form_valid(self, form: AuthenticationForm) -> HttpResponseRedirect:
|
||||||
|
"""Ensure that form can have type AuthenticationForm."""
|
||||||
|
form.get_user()
|
||||||
|
return HttpResponseRedirect(self.get_success_url())
|
||||||
Reference in New Issue
Block a user