Skip to content

Commit a4bbe09

Browse files
authored
Merge branch 'adamghill:main' into main
2 parents 6c679d5 + 78f3e30 commit a4bbe09

File tree

22 files changed

+1538
-631
lines changed

22 files changed

+1538
-631
lines changed

.all-contributorsrc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,24 @@
221221
"contributions": [
222222
"code"
223223
]
224+
},
225+
{
226+
"login": "imankulov",
227+
"name": "Roman Imankulov",
228+
"avatar_url": "https://avatars.githubusercontent.com/u/75075?v=4",
229+
"profile": "https://roman.pt",
230+
"contributions": [
231+
"test"
232+
]
233+
},
234+
{
235+
"login": "rhymiz",
236+
"name": "Lemi Boyce",
237+
"avatar_url": "https://avatars.githubusercontent.com/u/7029352?v=4",
238+
"profile": "https://github.com/rhymiz",
239+
"contributions": [
240+
"code"
241+
]
224242
}
225243
],
226244
"contributorsPerLine": 7,

.github/workflows/python.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ jobs:
66
runs-on: ubuntu-latest
77
strategy:
88
matrix:
9-
python-version: [3.7, 3.8, 3.9, "3.10"]
9+
python-version: [3.8, 3.9, "3.10", "3.11"]
1010

1111
steps:
1212
- uses: actions/[email protected]
@@ -21,11 +21,10 @@ jobs:
2121
- name: Install Poetry
2222
uses: abatilo/[email protected]
2323
with:
24-
poetry-version: 1.1.15
24+
poetry-version: 1.6.1
2525

2626
- name: Set Poetry config
2727
run: |
28-
poetry config virtualenvs.in-project false
2928
poetry config virtualenvs.path ~/.virtualenvs${{ matrix.python-version }}
3029
3130
- name: Install dependencies

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ Thanks to the following wonderful people ([emoji key](https://allcontributors.or
218218
<tr>
219219
<td align="center" valign="top" width="14.28%"><a href="https://marteydodoo.com"><img src="https://avatars.githubusercontent.com/u/49076?v=4?s=100" width="100px;" alt="Martey Dodoo"/><br /><sub><b>Martey Dodoo</b></sub></a><br /><a href="https://github.com/adamghill/django-unicorn/commits?author=martey" title="Documentation">📖</a></td>
220220
<td align="center" valign="top" width="14.28%"><a href="https://digitalpinup.art"><img src="https://avatars.githubusercontent.com/u/1392097?v=4?s=100" width="100px;" alt="Pierre"/><br /><sub><b>Pierre</b></sub></a><br /><a href="https://github.com/adamghill/django-unicorn/commits?author=bloodywing" title="Code">💻</a></td>
221+
<td align="center" valign="top" width="14.28%"><a href="https://roman.pt"><img src="https://avatars.githubusercontent.com/u/75075?v=4?s=100" width="100px;" alt="Roman Imankulov"/><br /><sub><b>Roman Imankulov</b></sub></a><br /><a href="https://github.com/adamghill/django-unicorn/commits?author=imankulov" title="Tests">⚠️</a></td>
222+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/rhymiz"><img src="https://avatars.githubusercontent.com/u/7029352?v=4?s=100" width="100px;" alt="Lemi Boyce"/><br /><sub><b>Lemi Boyce</b></sub></a><br /><a href="https://github.com/adamghill/django-unicorn/commits?author=rhymiz" title="Code">💻</a></td>
221223
</tr>
222224
</tbody>
223225
</table>

django_unicorn/settings.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,10 @@ def get_minify_html_enabled():
7373

7474
if minify_html_enabled:
7575
try:
76-
import htmlmin
76+
import htmlmin # noqa: F401
7777
except ModuleNotFoundError:
7878
logger.error(
79-
"MINIFY_HTML is `True`, but minify extra could not be imported. Install with `unicorn[minify]`."
79+
"MINIFY_HTML is `True`, but minify extra could not be imported. Install with `django-unicorn[minify]`."
8080
)
8181

8282
return False

django_unicorn/static/unicorn/js/messageSender.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ export function send(component, callback) {
136136
component.hash = responseJson.hash;
137137

138138
let parent = responseJson.parent || {};
139-
const rerenderedComponent = responseJson.dom || {};
139+
const rerenderedComponent = responseJson.dom || "";
140140
const partials = responseJson.partials || [];
141141
const { checksum } = responseJson;
142142

django_unicorn/static/unicorn/js/unicorn.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

django_unicorn/utils.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,12 +285,21 @@ def cast_value(type_hint, value):
285285

286286
type_hints = []
287287

288-
if get_origin(type_hint) is Union:
288+
if get_origin(type_hint) is Union or get_origin(type_hint) is list:
289289
for arg in get_args(type_hint):
290290
type_hints.append(arg)
291291
else:
292292
type_hints.append(type_hint)
293293

294+
if get_origin(type_hint) is list:
295+
if len(type_hints) == 1:
296+
# There should only be one argument for a list type hint
297+
arg = type_hints[0]
298+
299+
# Handle type hints that are a list by looping over the value and
300+
# casting each item individually
301+
return [cast_value(arg, item) for item in value]
302+
294303
for type_hint in type_hints:
295304
caster = CASTERS.get(type_hint)
296305

django_unicorn/views/__init__.py

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -260,16 +260,18 @@ def _process_component_request(
260260
key: component_request.data[key] for key in sorted(component_request.data)
261261
}
262262

263-
res = {
263+
result = {
264264
"id": component_request.id,
265265
"data": updated_data,
266266
"errors": component.errors,
267267
"calls": component.calls,
268268
"checksum": generate_checksum(str(component_request.data)),
269269
}
270270

271+
render_not_modified = False
272+
271273
if partial_doms:
272-
res.update({"partials": partial_doms})
274+
result.update({"partials": partial_doms})
273275
else:
274276
hash = generate_checksum(rendered_component)
275277

@@ -278,42 +280,46 @@ def _process_component_request(
278280
and (not return_data or not return_data.value)
279281
and not component.calls
280282
):
281-
raise RenderNotModified()
283+
if not component.parent:
284+
raise RenderNotModified()
285+
else:
286+
render_not_modified = True
282287

283-
# Make sure that partials with comments or blank lines before the root element only return the root element
288+
# Make sure that partials with comments or blank lines before the root element
289+
# only return the root element
284290
soup = BeautifulSoup(rendered_component, features="html.parser")
285291
rendered_component = str(get_root_element(soup))
286292

287-
res.update(
293+
result.update(
288294
{
289295
"dom": rendered_component,
290296
"hash": hash,
291297
}
292298
)
293299

294300
if return_data:
295-
res.update(
301+
result.update(
296302
{
297303
"return": return_data.get_data(),
298304
}
299305
)
300306

301307
if return_data.redirect:
302-
res.update(
308+
result.update(
303309
{
304310
"redirect": return_data.redirect,
305311
}
306312
)
307313

308314
if return_data.poll:
309-
res.update(
315+
result.update(
310316
{
311317
"poll": return_data.poll,
312318
}
313319
)
314320

315321
parent_component = component.parent
316-
parent_res = res
322+
parent_result = result
317323

318324
while parent_component:
319325
# TODO: Should parent_component.hydrate() be called?
@@ -339,12 +345,22 @@ def _process_component_request(
339345
}
340346
)
341347

342-
parent_res.update({"parent": parent})
348+
if render_not_modified:
349+
# TODO: Determine if all parents have not changed and return a 304 if
350+
# that's the case
351+
# i.e. render_not_modified = render_not_modified and (parent hash test)
352+
pass
353+
354+
# If there is a parent dom and a child dom, remove the child dom because it is superfluous
355+
if parent.get("dom") and result.get("dom"):
356+
del result["dom"]
357+
358+
parent_result.update({"parent": parent})
343359
component = parent_component
344360
parent_component = parent_component.parent
345-
parent_res = parent
361+
parent_result = parent
346362

347-
return res
363+
return result
348364

349365

350366
def _handle_component_request(

django_unicorn/views/action_parsers/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class TestView(UnicornView):
4646
component_or_field = component
4747
data_or_dict = data # Could be an internal portion of data that gets set
4848

49-
for (idx, property_name_part) in enumerate(property_name_parts):
49+
for idx, property_name_part in enumerate(property_name_parts):
5050
if hasattr(component_or_field, property_name_part):
5151
if idx == len(property_name_parts) - 1:
5252
if hasattr(component_or_field, "_set_property"):

docs/source/changelog.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Changelog
22

3+
## 0.55.0
4+
5+
- Support `List`/`list` type annotations for component actions and fields ([#582](https://github.com/adamghill/django-unicorn/pull/582)).
6+
- Fix: calling a method in a parent will have the request available ([#583]https://github.com/adamghill/django-unicorn/pull/583).
7+
8+
**Breaking changes**
9+
10+
- Dropped official support for Python 3.7 because its [end of life was June 27, 2023](https://endoflife.date/python).
11+
- Dropped official support for Django 2.2 because its [end of life was April 1, 2022](https://endoflife.date/django).
12+
313
## 0.54.0
414

515
- Coerce type annotated arguments in an action method to the specified type ([#571](https://github.com/adamghill/django-unicorn/pull/571)).

0 commit comments

Comments
 (0)