11from collections import OrderedDict
2- from typing import Any , Callable , Dict , Iterator , List , Optional , Sequence , Set , Tuple , Type , Union , Mapping , TypeVar
2+ from typing import (
3+ Any ,
4+ Callable ,
5+ Dict ,
6+ Generic ,
7+ Iterator ,
8+ List ,
9+ Optional ,
10+ Sequence ,
11+ Set ,
12+ Tuple ,
13+ Type ,
14+ Union ,
15+ Mapping ,
16+ TypeVar ,
17+ )
318
419from django .forms .forms import BaseForm
520from django .forms .formsets import BaseFormSet
@@ -57,7 +72,11 @@ _T = TypeVar("_T")
5772_ListOrTuple = Union [Tuple [_T , ...], List [_T ]]
5873_FieldsetSpec = _ListOrTuple [Tuple [Optional [str ], _FieldOpts ]]
5974
60- class BaseModelAdmin :
75+ # Generic type specifically for models, for use in BaseModelAdmin and subclasses
76+ # https://github.com/typeddjango/django-stubs/issues/482
77+ _ModelT = TypeVar ("_ModelT" , bound = Model )
78+
79+ class BaseModelAdmin (Generic [_ModelT ]):
6180 autocomplete_fields : Sequence [str ] = ...
6281 raw_id_fields : Sequence [str ] = ...
6382 fields : Sequence [Union [str , Sequence [str ]]] = ...
@@ -69,7 +88,7 @@ class BaseModelAdmin:
6988 radio_fields : Mapping [str , _Direction ] = ...
7089 prepopulated_fields : Mapping [str , Sequence [str ]] = ...
7190 formfield_overrides : Mapping [Type [Field ], Mapping [str , Any ]] = ...
72- readonly_fields : Sequence [Union [str , Callable [[Model ], Any ]]] = ...
91+ readonly_fields : Sequence [Union [str , Callable [[_ModelT ], Any ]]] = ...
7392 ordering : Sequence [str ] = ...
7493 sortable_by : Sequence [str ] = ...
7594 view_on_site : bool = ...
@@ -92,28 +111,28 @@ class BaseModelAdmin:
92111 self , db_field : ManyToManyField , request : Optional [HttpRequest ], ** kwargs : Any
93112 ) -> ModelMultipleChoiceField : ...
94113 def get_autocomplete_fields (self , request : HttpRequest ) -> Tuple : ...
95- def get_view_on_site_url (self , obj : Optional [Model ] = ...) -> Optional [str ]: ...
114+ def get_view_on_site_url (self , obj : Optional [_ModelT ] = ...) -> Optional [str ]: ...
96115 def get_empty_value_display (self ) -> SafeText : ...
97- def get_exclude (self , request : HttpRequest , obj : Optional [Model ] = ...) -> Any : ...
98- def get_fields (self , request : HttpRequest , obj : Optional [Model ] = ...) -> Sequence [Union [Callable , str ]]: ...
116+ def get_exclude (self , request : HttpRequest , obj : Optional [_ModelT ] = ...) -> Any : ...
117+ def get_fields (self , request : HttpRequest , obj : Optional [_ModelT ] = ...) -> Sequence [Union [Callable , str ]]: ...
99118 def get_fieldsets (
100- self , request : HttpRequest , obj : Optional [Model ] = ...
119+ self , request : HttpRequest , obj : Optional [_ModelT ] = ...
101120 ) -> List [Tuple [Optional [str ], Dict [str , Any ]]]: ...
102121 def get_ordering (self , request : HttpRequest ) -> Union [List [str ], Tuple ]: ...
103- def get_readonly_fields (self , request : HttpRequest , obj : Optional [Model ] = ...) -> Union [List [str ], Tuple ]: ...
104- def get_prepopulated_fields (self , request : HttpRequest , obj : Optional [Model ] = ...) -> Dict [str , Tuple [str ]]: ...
122+ def get_readonly_fields (self , request : HttpRequest , obj : Optional [_ModelT ] = ...) -> Union [List [str ], Tuple ]: ...
123+ def get_prepopulated_fields (self , request : HttpRequest , obj : Optional [_ModelT ] = ...) -> Dict [str , Tuple [str ]]: ...
105124 def get_queryset (self , request : HttpRequest ) -> QuerySet : ...
106125 def get_sortable_by (self , request : HttpRequest ) -> Union [List [Callable ], List [str ], Tuple ]: ...
107126 def lookup_allowed (self , lookup : str , value : str ) -> bool : ...
108127 def to_field_allowed (self , request : HttpRequest , to_field : str ) -> bool : ...
109128 def has_add_permission (self , request : HttpRequest ) -> bool : ...
110- def has_change_permission (self , request : HttpRequest , obj : Optional [Model ] = ...) -> bool : ...
111- def has_delete_permission (self , request : HttpRequest , obj : Optional [Model ] = ...) -> bool : ...
112- def has_view_permission (self , request : HttpRequest , obj : Optional [Model ] = ...) -> bool : ...
129+ def has_change_permission (self , request : HttpRequest , obj : Optional [_ModelT ] = ...) -> bool : ...
130+ def has_delete_permission (self , request : HttpRequest , obj : Optional [_ModelT ] = ...) -> bool : ...
131+ def has_view_permission (self , request : HttpRequest , obj : Optional [_ModelT ] = ...) -> bool : ...
113132 def has_module_permission (self , request : HttpRequest ) -> bool : ...
114133
115- class ModelAdmin (BaseModelAdmin ):
116- list_display : Sequence [Union [str , Callable [[Model ], Any ]]] = ...
134+ class ModelAdmin (BaseModelAdmin [ _ModelT ] ):
135+ list_display : Sequence [Union [str , Callable [[_ModelT ], Any ]]] = ...
117136 list_display_links : Optional [Sequence [Union [str , Callable ]]] = ...
118137 list_filter : Sequence [Union [str , Type [ListFilter ], Tuple [str , Type [ListFilter ]]]] = ...
119138 list_select_related : Union [bool , Sequence [str ]] = ...
@@ -140,24 +159,24 @@ class ModelAdmin(BaseModelAdmin):
140159 actions_on_top : bool = ...
141160 actions_on_bottom : bool = ...
142161 actions_selection_counter : bool = ...
143- model : Type [Model ] = ...
162+ model : Type [_ModelT ] = ...
144163 opts : Options = ...
145164 admin_site : AdminSite = ...
146- def __init__ (self , model : Type [Model ], admin_site : Optional [AdminSite ]) -> None : ...
147- def get_inline_instances (self , request : HttpRequest , obj : Optional [Model ] = ...) -> List [InlineModelAdmin ]: ...
165+ def __init__ (self , model : Type [_ModelT ], admin_site : Optional [AdminSite ]) -> None : ...
166+ def get_inline_instances (self , request : HttpRequest , obj : Optional [_ModelT ] = ...) -> List [InlineModelAdmin ]: ...
148167 def get_urls (self ) -> List [URLPattern ]: ...
149168 @property
150169 def urls (self ) -> List [URLPattern ]: ...
151170 @property
152171 def media (self ) -> Media : ...
153172 def get_model_perms (self , request : HttpRequest ) -> Dict [str , bool ]: ...
154- def get_form (self , request : Any , obj : Optional [Any ] = ..., change : bool = ..., ** kwargs : Any ): ...
173+ def get_form (self , request : Any , obj : Optional [_ModelT ] = ..., change : bool = ..., ** kwargs : Any ): ...
155174 def get_changelist (self , request : HttpRequest , ** kwargs : Any ) -> Type [ChangeList ]: ...
156175 def get_changelist_instance (self , request : HttpRequest ) -> ChangeList : ...
157- def get_object (self , request : HttpRequest , object_id : str , from_field : None = ...) -> Optional [Model ]: ...
176+ def get_object (self , request : HttpRequest , object_id : str , from_field : None = ...) -> Optional [_ModelT ]: ...
158177 def get_changelist_form (self , request : Any , ** kwargs : Any ): ...
159178 def get_changelist_formset (self , request : Any , ** kwargs : Any ): ...
160- def get_formsets_with_inlines (self , request : HttpRequest , obj : Optional [Model ] = ...) -> Iterator [Any ]: ...
179+ def get_formsets_with_inlines (self , request : HttpRequest , obj : Optional [_ModelT ] = ...) -> Iterator [Any ]: ...
161180 def get_paginator (
162181 self ,
163182 request : HttpRequest ,
@@ -166,10 +185,10 @@ class ModelAdmin(BaseModelAdmin):
166185 orphans : int = ...,
167186 allow_empty_first_page : bool = ...,
168187 ) -> Paginator : ...
169- def log_addition (self , request : HttpRequest , object : Model , message : Any ) -> LogEntry : ...
170- def log_change (self , request : HttpRequest , object : Model , message : Any ) -> LogEntry : ...
171- def log_deletion (self , request : HttpRequest , object : Model , object_repr : str ) -> LogEntry : ...
172- def action_checkbox (self , obj : Model ) -> SafeText : ...
188+ def log_addition (self , request : HttpRequest , object : _ModelT , message : Any ) -> LogEntry : ...
189+ def log_change (self , request : HttpRequest , object : _ModelT , message : Any ) -> LogEntry : ...
190+ def log_deletion (self , request : HttpRequest , object : _ModelT , object_repr : str ) -> LogEntry : ...
191+ def action_checkbox (self , obj : _ModelT ) -> SafeText : ...
173192 def get_actions (self , request : HttpRequest ) -> OrderedDict : ...
174193 def get_action_choices (
175194 self , request : HttpRequest , default_choices : List [Tuple [str , str ]] = ...
@@ -198,8 +217,8 @@ class ModelAdmin(BaseModelAdmin):
198217 fail_silently : bool = ...,
199218 ) -> None : ...
200219 def save_form (self , request : Any , form : Any , change : Any ): ...
201- def save_model (self , request : Any , obj : Any , form : Any , change : Any ) -> None : ...
202- def delete_model (self , request : HttpRequest , obj : Model ) -> None : ...
220+ def save_model (self , request : Any , obj : _ModelT , form : Any , change : Any ) -> None : ...
221+ def delete_model (self , request : HttpRequest , obj : _ModelT ) -> None : ...
203222 def delete_queryset (self , request : HttpRequest , queryset : QuerySet ) -> None : ...
204223 def save_formset (self , request : Any , form : Any , formset : Any , change : Any ) -> None : ...
205224 def save_related (self , request : Any , form : Any , formsets : Any , change : Any ) -> None : ...
@@ -210,19 +229,19 @@ class ModelAdmin(BaseModelAdmin):
210229 add : bool = ...,
211230 change : bool = ...,
212231 form_url : str = ...,
213- obj : Optional [Any ] = ...,
232+ obj : Optional [_ModelT ] = ...,
214233 ): ...
215234 def response_add (
216- self , request : HttpRequest , obj : Model , post_url_continue : Optional [str ] = ...
235+ self , request : HttpRequest , obj : _ModelT , post_url_continue : Optional [str ] = ...
217236 ) -> HttpResponse : ...
218- def response_change (self , request : HttpRequest , obj : Model ) -> HttpResponse : ...
219- def response_post_save_add (self , request : HttpRequest , obj : Model ) -> HttpResponseRedirect : ...
220- def response_post_save_change (self , request : HttpRequest , obj : Model ) -> HttpResponseRedirect : ...
237+ def response_change (self , request : HttpRequest , obj : _ModelT ) -> HttpResponse : ...
238+ def response_post_save_add (self , request : HttpRequest , obj : _ModelT ) -> HttpResponseRedirect : ...
239+ def response_post_save_change (self , request : HttpRequest , obj : _ModelT ) -> HttpResponseRedirect : ...
221240 def response_action (self , request : HttpRequest , queryset : QuerySet ) -> Optional [HttpResponseBase ]: ...
222241 def response_delete (self , request : HttpRequest , obj_display : str , obj_id : int ) -> HttpResponse : ...
223242 def render_delete_form (self , request : Any , context : Any ): ...
224243 def get_inline_formsets (
225- self , request : HttpRequest , formsets : List [Any ], inline_instances : List [Any ], obj : Optional [Model ] = ...
244+ self , request : HttpRequest , formsets : List [Any ], inline_instances : List [Any ], obj : Optional [_ModelT ] = ...
226245 ) -> List [Any ]: ...
227246 def get_changeform_initial_data (self , request : HttpRequest ) -> Dict [str , str ]: ...
228247 def changeform_view (
@@ -246,8 +265,8 @@ class ModelAdmin(BaseModelAdmin):
246265 def delete_view (self , request : HttpRequest , object_id : str , extra_context : None = ...) -> Any : ...
247266 def history_view (self , request : HttpRequest , object_id : str , extra_context : None = ...) -> HttpResponse : ...
248267
249- class InlineModelAdmin (BaseModelAdmin ):
250- model : Type [Model ] = ...
268+ class InlineModelAdmin (BaseModelAdmin [ _ModelT ] ):
269+ model : Type [_ModelT ] = ...
251270 fk_name : str = ...
252271 formset : BaseFormSet = ...
253272 extra : int = ...
@@ -263,13 +282,13 @@ class InlineModelAdmin(BaseModelAdmin):
263282 parent_model : Any = ...
264283 opts : Any = ...
265284 has_registered_model : Any = ...
266- def __init__ (self , parent_model : Union [Type [Model ], Model ], admin_site : AdminSite ) -> None : ...
285+ def __init__ (self , parent_model : Union [Type [_ModelT ], _ModelT ], admin_site : AdminSite ) -> None : ...
267286 @property
268287 def media (self ) -> Media : ...
269- def get_extra (self , request : HttpRequest , obj : Optional [Model ] = ..., ** kwargs : Any ) -> int : ...
270- def get_min_num (self , request : HttpRequest , obj : Optional [Model ] = ..., ** kwargs : Any ) -> Optional [int ]: ...
271- def get_max_num (self , request : HttpRequest , obj : Optional [Model ] = ..., ** kwargs : Any ) -> Optional [int ]: ...
272- def get_formset (self , request : Any , obj : Optional [Any ] = ..., ** kwargs : Any ): ...
288+ def get_extra (self , request : HttpRequest , obj : Optional [_ModelT ] = ..., ** kwargs : Any ) -> int : ...
289+ def get_min_num (self , request : HttpRequest , obj : Optional [_ModelT ] = ..., ** kwargs : Any ) -> Optional [int ]: ...
290+ def get_max_num (self , request : HttpRequest , obj : Optional [_ModelT ] = ..., ** kwargs : Any ) -> Optional [int ]: ...
291+ def get_formset (self , request : Any , obj : Optional [_ModelT ] = ..., ** kwargs : Any ): ...
273292
274- class StackedInline (InlineModelAdmin ): ...
275- class TabularInline (InlineModelAdmin ): ...
293+ class StackedInline (InlineModelAdmin [ _ModelT ] ): ...
294+ class TabularInline (InlineModelAdmin [ _ModelT ] ): ...
0 commit comments