14
14
from idom .backend .types import Location
15
15
from idom .core .hooks import Context , create_context , use_context , use_effect , use_state
16
16
17
- from django_idom .types import IdomWebsocket , Mutation , OrmFetch , Query , _Params , _Result
17
+ from django_idom .types import (
18
+ IdomWebsocket ,
19
+ Mutation ,
20
+ QueryOptions ,
21
+ Query ,
22
+ _Params ,
23
+ _Result ,
24
+ )
18
25
from django_idom .utils import _generate_obj_name
19
26
20
27
@@ -68,7 +75,7 @@ def use_websocket() -> IdomWebsocket:
68
75
69
76
70
77
def use_query (
71
- query : Callable [_Params , _Result | None ] | OrmFetch ,
78
+ query : Callable [_Params , _Result | None ] | QueryOptions ,
72
79
* args : _Params .args ,
73
80
** kwargs : _Params .kwargs ,
74
81
) -> Query [_Result | None ]:
@@ -88,7 +95,9 @@ def use_query(
88
95
data , set_data = use_state (cast (Union [_Result , None ], None ))
89
96
loading , set_loading = use_state (True )
90
97
error , set_error = use_state (cast (Union [Exception , None ], None ))
91
- fetch_cls = query if isinstance (query , OrmFetch ) else OrmFetch (query )
98
+ query_options = (
99
+ query if isinstance (query , QueryOptions ) else QueryOptions (func = query )
100
+ )
92
101
93
102
@use_callback
94
103
def refetch () -> None :
@@ -100,8 +109,8 @@ def refetch() -> None:
100
109
def add_refetch_callback () -> Callable [[], None ]:
101
110
# By tracking callbacks globally, any usage of the query function will be re-run
102
111
# if the user has told a mutation to refetch it.
103
- _REFETCH_CALLBACKS [fetch_cls .func ].add (refetch )
104
- return lambda : _REFETCH_CALLBACKS [fetch_cls .func ].remove (refetch )
112
+ _REFETCH_CALLBACKS [query_options .func ].add (refetch )
113
+ return lambda : _REFETCH_CALLBACKS [query_options .func ].remove (refetch )
105
114
106
115
@use_effect (dependencies = None )
107
116
@database_sync_to_async
@@ -111,15 +120,15 @@ def execute_query() -> None:
111
120
112
121
try :
113
122
# Run the initial query
114
- fetch_cls . data = fetch_cls .func (* args , ** kwargs )
123
+ query_options . _data = query_options .func (* args , ** kwargs )
115
124
116
- # Use a custom evaluator , if provided
117
- if fetch_cls . evaluator :
118
- fetch_cls . evaluator ( fetch_cls )
125
+ # Use a custom postprocessor , if provided
126
+ if query_options . postprocessor :
127
+ query_options . postprocessor ( query_options )
119
128
120
- # Evaluate lazy Django fields
129
+ # Use the default postprocessor
121
130
else :
122
- _evaluate_django_query ( fetch_cls )
131
+ _postprocess_django_query ( query_options )
123
132
except Exception as e :
124
133
set_data (None )
125
134
set_loading (False )
@@ -131,7 +140,7 @@ def execute_query() -> None:
131
140
finally :
132
141
set_should_execute (False )
133
142
134
- set_data (fetch_cls . data )
143
+ set_data (query_options . _data )
135
144
set_loading (False )
136
145
set_error (None )
137
146
@@ -191,21 +200,21 @@ def reset() -> None:
191
200
return Mutation (call , loading , error , reset )
192
201
193
202
194
- def _evaluate_django_query (fetch_cls : OrmFetch ) -> None :
203
+ def _postprocess_django_query (fetch_cls : QueryOptions ) -> None :
195
204
"""Recursively fetch all fields within a `Model` or `QuerySet` to ensure they are not performed lazily.
196
205
197
206
Some behaviors can be modified through `OrmFetch` attributes."""
198
- data = fetch_cls .data
207
+ data = fetch_cls ._data
199
208
200
209
# `QuerySet`, which is effectively a list of `Model` instances
201
210
# https://github.com/typeddjango/django-stubs/issues/704
202
211
if isinstance (data , QuerySet ): # type: ignore[misc]
203
212
for model in data :
204
- _evaluate_django_query (
205
- OrmFetch (
213
+ _postprocess_django_query (
214
+ QueryOptions (
206
215
func = fetch_cls .func ,
207
- data = model ,
208
- options = fetch_cls .options ,
216
+ _data = model ,
217
+ postprocessor_options = fetch_cls .postprocessor_options ,
209
218
)
210
219
)
211
220
@@ -219,20 +228,20 @@ def _evaluate_django_query(fetch_cls: OrmFetch) -> None:
219
228
getattr (data , field .name )
220
229
221
230
if (
222
- fetch_cls .options .get ("many_to_one" , None )
231
+ fetch_cls .postprocessor_options .get ("many_to_one" , None )
223
232
and type (field ) == ManyToOneRel
224
233
):
225
234
prefetch_fields .append (f"{ field .name } _set" )
226
235
227
- elif fetch_cls .options .get ( "many_to_many" , None ) and isinstance (
228
- field , ManyToManyField
229
- ):
236
+ elif fetch_cls .postprocessor_options .get (
237
+ "many_to_many" , None
238
+ ) and isinstance ( field , ManyToManyField ) :
230
239
prefetch_fields .append (field .name )
231
- _evaluate_django_query (
232
- OrmFetch (
240
+ _postprocess_django_query (
241
+ QueryOptions (
233
242
func = fetch_cls .func ,
234
- data = getattr (data , field .name ).get_queryset (),
235
- options = fetch_cls .options ,
243
+ _data = getattr (data , field .name ).get_queryset (),
244
+ postprocessor_options = fetch_cls .postprocessor_options ,
236
245
)
237
246
)
238
247
0 commit comments