Skip to content

Commit c72c3b9

Browse files
committed
Merge remote-tracking branch 'origin/main' into loosen
# Conflicts: # django_unicorn/static/unicorn/js/unicorn.min.js # pyproject.toml
2 parents e411996 + a4bbe09 commit c72c3b9

File tree

22 files changed

+1541
-634
lines changed

22 files changed

+1541
-634
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
@@ -270,6 +270,8 @@ Thanks to the following wonderful people ([emoji key](https://allcontributors.or
270270
<tr>
271271
<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>
272272
<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>
273+
<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>
274+
<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>
273275
</tr>
274276
</tbody>
275277
</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
@@ -147,7 +147,7 @@ export function send(component, callback) {
147147
component.hash = responseJson.hash;
148148

149149
let parent = responseJson.parent || {};
150-
const rerenderedComponent = responseJson.dom || {};
150+
const rerenderedComponent = responseJson.dom || "";
151151
const partials = responseJson.partials || [];
152152
const { checksum } = responseJson;
153153

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

Lines changed: 2 additions & 2 deletions
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
@@ -261,16 +261,18 @@ def _process_component_request(
261261
key: component_request.data[key] for key in sorted(component_request.data)
262262
}
263263

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

272+
render_not_modified = False
273+
272274
if partial_doms:
273-
res.update({"partials": partial_doms})
275+
result.update({"partials": partial_doms})
274276
else:
275277
hash = generate_checksum(rendered_component)
276278

@@ -279,42 +281,46 @@ def _process_component_request(
279281
and (not return_data or not return_data.value)
280282
and not component.calls
281283
):
282-
raise RenderNotModified()
284+
if not component.parent:
285+
raise RenderNotModified()
286+
else:
287+
render_not_modified = True
283288

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

288-
res.update(
294+
result.update(
289295
{
290296
"dom": rendered_component,
291297
"hash": hash,
292298
}
293299
)
294300

295301
if return_data:
296-
res.update(
302+
result.update(
297303
{
298304
"return": return_data.get_data(),
299305
}
300306
)
301307

302308
if return_data.redirect:
303-
res.update(
309+
result.update(
304310
{
305311
"redirect": return_data.redirect,
306312
}
307313
)
308314

309315
if return_data.poll:
310-
res.update(
316+
result.update(
311317
{
312318
"poll": return_data.poll,
313319
}
314320
)
315321

316322
parent_component = component.parent
317-
parent_res = res
323+
parent_result = result
318324

319325
while parent_component:
320326
# TODO: Should parent_component.hydrate() be called?
@@ -340,12 +346,22 @@ def _process_component_request(
340346
}
341347
)
342348

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

348-
return res
364+
return result
349365

350366

351367
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)