|
1 | 1 | import json
|
| 2 | +from inspect import signature |
2 | 3 | from django.core.exceptions import ImproperlyConfigured
|
3 | 4 | from django.views.generic import View
|
4 | 5 | from django.views.generic.list import BaseListView
|
|
20 | 21 | log = logging.getLogger(__name__)
|
21 | 22 |
|
22 | 23 |
|
| 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 | + |
23 | 36 | def _build_context(component_name, props, version, url):
|
24 | 37 | context = {
|
25 | 38 | "page": {
|
@@ -72,17 +85,34 @@ def render_inertia(request, component_name, props=None, template_name=None):
|
72 | 85 | inertia_version = get_version()
|
73 | 86 | is_version_correct = 'X-Inertia-Version' in request.headers and \
|
74 | 87 | 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 | + |
75 | 105 | if 'X-Inertia' in request.headers:
|
76 | 106 | response = JsonResponse({
|
77 | 107 | "component": component_name,
|
78 |
| - "props": props, |
| 108 | + "props": _props, |
79 | 109 | "version": inertia_version,
|
80 | 110 | "url": request.get_full_path()
|
81 | 111 | })
|
82 | 112 | response['X-Inertia'] = True
|
83 | 113 | response['Vary'] = 'Accept'
|
84 | 114 | return response
|
85 |
| - context = _build_context(component_name, props, |
| 115 | + context = _build_context(component_name, _props, |
86 | 116 | inertia_version,
|
87 | 117 | url=request.get_full_path())
|
88 | 118 | return render(request, inertia_template, context)
|
|
0 commit comments