Skip to content

Commit 5b7dcc0

Browse files
committed
fetch deferred attrs
1 parent a863ad3 commit 5b7dcc0

File tree

1 file changed

+36
-5
lines changed

1 file changed

+36
-5
lines changed

src/django_idom/hooks.py

+36-5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
NamedTuple,
1818
)
1919

20+
from django.db.models.base import Model
21+
from django.db.models.query import QuerySet
2022
from typing_extensions import ParamSpec
2123
from idom import use_callback
2224

@@ -71,6 +73,7 @@ def use_websocket() -> IdomWebsocket:
7173
def use_query(
7274
query: Callable[_Params, _Data],
7375
*args: _Params.args,
76+
fetch_deferred_fields: bool = True,
7477
**kwargs: _Params.kwargs,
7578
) -> Query[_Data]:
7679
given_query = query
@@ -102,15 +105,33 @@ def execute_query():
102105

103106
def thread_target():
104107
try:
105-
returned = query(*args, **kwargs)
108+
query_result = query(*args, **kwargs)
106109
except Exception as e:
107110
set_data(UNDEFINED)
108111
set_loading(False)
109112
set_error(e)
110-
else:
111-
set_data(returned)
112-
set_loading(False)
113-
set_error(None)
113+
return
114+
115+
if isinstance(query_result, QuerySet):
116+
if fetch_deferred_fields:
117+
for model in query_result:
118+
_fetch_deferred_fields(model)
119+
else:
120+
# still force query set to execute
121+
for _ in query_result:
122+
pass
123+
elif isinstance(query_result, Model):
124+
if fetch_deferred_fields:
125+
_fetch_deferred_fields(query_result)
126+
elif fetch_deferred_fields:
127+
raise ValueError(
128+
f"Expected {query} to return Model or Query because "
129+
f"{fetch_deferred_fields=}, got {query_result!r}"
130+
)
131+
132+
set_data(query_result)
133+
set_loading(False)
134+
set_error(None)
114135

115136
# We need to run this in a thread so we don't prevent rendering when loading.
116137
# I'm also hoping that Django is ok with this since this thread won't have an
@@ -170,3 +191,13 @@ class Mutation(NamedTuple, Generic[_Params]):
170191
loading: bool
171192
error: Exception | None
172193
reset: Callable[[], None]
194+
195+
196+
_Model = TypeVar("_Model", bound=Model)
197+
198+
199+
def _fetch_deferred_fields(model: _Model) -> _Model:
200+
for field in model.get_deferred_fields():
201+
value = getattr(model, field)
202+
if isinstance(value, Model):
203+
_fetch_deferred_fields(value)

0 commit comments

Comments
 (0)