1818
1919from asgiref .sync import sync_to_async
2020from django .db .models import QuerySet
21- from ninja import Field , Query , Schema
21+ from django .http import HttpRequest
22+ from ninja import Field , P , Query , Schema
2223from ninja .constants import NOT_SET
2324from ninja .signature import is_async
2425from pydantic import BaseModel
@@ -65,14 +66,24 @@ def __init__(
6566 ) -> None :
6667 super ().__init__ (pass_parameter = pass_parameter )
6768 self .ordering_fields = ordering_fields or "__all__"
69+ self .Input = self .create_input (ordering_fields ) # type:ignore
70+
71+ def create_input (self , ordering_fields : Optional [List [str ]]) -> Type [Input ]:
72+ if ordering_fields :
73+
74+ class DynamicInput (Ordering .Input ):
75+ ordering : Query [Optional [str ], P (default = "," .join (ordering_fields ))] # type:ignore[type-arg,valid-type]
76+
77+ return DynamicInput
78+ return Ordering .Input
6879
6980 def ordering_queryset (
7081 self , items : Union [QuerySet , List ], ordering_input : Input
7182 ) -> Union [QuerySet , List ]:
72- ordering = self .get_ordering (items , ordering_input .ordering )
73- if ordering :
83+ ordering_ = self .get_ordering (items , ordering_input .ordering )
84+ if ordering_ :
7485 if isinstance (items , QuerySet ): # type:ignore
75- return items .order_by (* ordering )
86+ return items .order_by (* ordering_ )
7687 elif isinstance (items , list ) and items :
7788
7889 def multisort (xs : List , specs : List [Tuple [str , bool ]]) -> List :
@@ -85,7 +96,7 @@ def multisort(xs: List, specs: List[Tuple[str, bool]]) -> List:
8596 items ,
8697 [
8798 (o [int (o .startswith ("-" )) :], o .startswith ("-" ))
88- for o in ordering
99+ for o in ordering_
89100 ],
90101 )
91102 return items
@@ -201,49 +212,51 @@ def __init__(
201212 self .view_func = view_func
202213
203214 orderator_view = self .get_view_function ()
204- _ninja_contribute_args : List [Tuple ] = getattr (
205- self .view_func , "_ninja_contribute_args" , []
206- )
207- orderator_view ._ninja_contribute_args = ( # type:ignore[attr-defined]
208- _ninja_contribute_args
209- )
215+ self .as_view = wraps (view_func )(orderator_view )
210216 add_ninja_contribute_args (
211- orderator_view ,
217+ self . as_view ,
212218 (
213219 self .orderator_kwargs_name ,
214220 self .orderator .Input ,
215221 self .orderator .InputSource ,
216222 ),
217223 )
218224 orderator_view .orderator_operation = self # type:ignore[attr-defined]
219- self .as_view = wraps (view_func )(orderator_view )
220225
221226 @property
222227 def view_func_has_kwargs (self ) -> bool : # pragma: no cover
223228 return self .orderator .pass_parameter is not None
224229
225230 def get_view_function (self ) -> Callable :
226- def as_view (controller : "ControllerBase" , * args : Any , ** kw : Any ) -> Any :
231+ def as_view (
232+ request_or_controller : Union ["ControllerBase" , HttpRequest ],
233+ * args : Any ,
234+ ** kw : Any ,
235+ ) -> Any :
227236 func_kwargs = dict (** kw )
228237 ordering_params = func_kwargs .pop (self .orderator_kwargs_name )
229238 if self .orderator .pass_parameter :
230239 func_kwargs [self .orderator .pass_parameter ] = ordering_params
231240
232- items = self .view_func (controller , * args , ** func_kwargs )
241+ items = self .view_func (request_or_controller , * args , ** func_kwargs )
233242 return self .orderator .ordering_queryset (items , ordering_params )
234243
235244 return as_view
236245
237246
238247class AsyncOrderatorOperation (OrderatorOperation ):
239248 def get_view_function (self ) -> Callable :
240- async def as_view (controller : "ControllerBase" , * args : Any , ** kw : Any ) -> Any :
249+ async def as_view (
250+ request_or_controller : Union ["ControllerBase" , HttpRequest ],
251+ * args : Any ,
252+ ** kw : Any ,
253+ ) -> Any :
241254 func_kwargs = dict (** kw )
242255 ordering_params = func_kwargs .pop (self .orderator_kwargs_name )
243256 if self .orderator .pass_parameter :
244257 func_kwargs [self .orderator .pass_parameter ] = ordering_params
245258
246- items = await self .view_func (controller , * args , ** func_kwargs )
259+ items = await self .view_func (request_or_controller , * args , ** func_kwargs )
247260 ordering_queryset = cast (
248261 Callable , sync_to_async (self .orderator .ordering_queryset )
249262 )
0 commit comments