Skip to content
This repository was archived by the owner on Dec 11, 2024. It is now read-only.

Commit 153d7ba

Browse files
authored
Merge pull request #7 from girardinsamuel/feat/add-partial-reloads
2 parents 7310502 + 9c93a6d commit 153d7ba

File tree

2 files changed

+60
-3
lines changed

2 files changed

+60
-3
lines changed

inertia/views.py

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
from inspect import signature
23
from django.core.exceptions import ImproperlyConfigured
34
from django.views.generic import View
45
from django.views.generic.list import BaseListView
@@ -20,6 +21,18 @@
2021
log = logging.getLogger(__name__)
2122

2223

24+
def load_lazy_props(d, request):
25+
for k, v in d.items():
26+
if isinstance(v, dict):
27+
load_lazy_props(v, request)
28+
elif callable(v):
29+
# evaluate prop and pass request if prop accept it
30+
if len(signature(v).parameters) > 0:
31+
d[k] = v(request)
32+
else:
33+
d[k] = v()
34+
35+
2336
def _build_context(component_name, props, version, url):
2437
context = {
2538
"page": {
@@ -72,17 +85,34 @@ def render_inertia(request, component_name, props=None, template_name=None):
7285
inertia_version = get_version()
7386
is_version_correct = 'X-Inertia-Version' in request.headers and \
7487
request.headers["X-Inertia-Version"] == str(inertia_version)
88+
89+
# check if partial reload is requested
90+
only_props = request.headers.get("X-Inertia-Partial-Data", [])
91+
if (
92+
only_props
93+
and request.headers.get("X-Inertia-Partial-Component", "") == component_name
94+
):
95+
_props = {}
96+
for key in props:
97+
if key in only_props:
98+
_props.update({key: props[key]})
99+
else:
100+
_props = props
101+
102+
# lazy load props and make request available to props being lazy loaded
103+
load_lazy_props(_props, request)
104+
75105
if 'X-Inertia' in request.headers:
76106
response = JsonResponse({
77107
"component": component_name,
78-
"props": props,
108+
"props": _props,
79109
"version": inertia_version,
80110
"url": request.get_full_path()
81111
})
82112
response['X-Inertia'] = True
83113
response['Vary'] = 'Accept'
84114
return response
85-
context = _build_context(component_name, props,
115+
context = _build_context(component_name, _props,
86116
inertia_version,
87117
url=request.get_full_path())
88118
return render(request, inertia_template, context)

test.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def test_middleware(self):
7070
'X-Inertia-Version': get_version(),
7171
'x-Requested-With': 'XMLHttpRequest'
7272
}
73-
request = RequestFactory().get("/", **defaults)
73+
request = RequestFactory().get("/") #, **defaults)
7474
request.headers = defaults
7575
self.set_session(request)
7676
response = InertiaMiddleware(view)(request)
@@ -99,3 +99,30 @@ def test_redirect_303_for_put_patch_delete_requests(self):
9999
self.set_session(request)
100100
response = InertiaMiddleware(lambda x: HttpResponseRedirect(redirect_to="/users"))(request)
101101
self.assertTrue(response.status_code==303, response.status_code)
102+
103+
def test_resolve_lazy_loading_props(self):
104+
requestfactory = RequestFactory()
105+
request = requestfactory.get("/")
106+
self.set_session(request)
107+
def lazy_loaded_prop():
108+
return "2"
109+
response = render_inertia(request, "Index", {"a": "1", "b": lazy_loaded_prop})
110+
self.assertTrue(b'"props": {"a": "1", "b": "2"}' in response.content)
111+
112+
def test_partial_loading(self):
113+
defaults = {
114+
'X-Inertia': 'true',
115+
'X-Inertia-Version': get_version(),
116+
'X-Requested-With': 'XMLHttpRequest',
117+
'X-Inertia-Partial-Data': ["a"],
118+
"X-Inertia-Partial-Component": "Index"
119+
}
120+
requestfactory = RequestFactory()
121+
request = requestfactory.get("/")
122+
request.headers = defaults
123+
self.set_session(request)
124+
def lazy_loaded_prop():
125+
return "2"
126+
response = render_inertia(request, "Index", {"a": "1", "b": lazy_loaded_prop})
127+
# check that b is not returned because we only ask for a
128+
self.assertIn(b'"props": {"a": "1"},', response.content)

0 commit comments

Comments
 (0)