diff --git a/docs/source/signal-decorator.md b/docs/source/signal-decorator.md index 36e87b5..c8f5fca 100644 --- a/docs/source/signal-decorator.md +++ b/docs/source/signal-decorator.md @@ -30,3 +30,19 @@ Notes: 2. The function decorated by `after_create_commit`, `after_update_commit`, receive the same arguments as `post_save` signal handler. 3. The function decorated by `after_delete_commit` receive the same arguments as `post_delete` signal handler. 4. This can make our code more clear, especially when we need to some broadcasts. + +## django-lifecycle + +Another approach is to use `django-lifecycle` package, which is inspired by Rails' `ActiveRecord` callbacks. + +So we can write the code in Django model like this: + +```python +@hook(AFTER_UPDATE, on_commit=True) +def broadcast_updated(self): + pass + +@hook(BEFORE_DELETE) +def broadcast_deleted(self): + pass +``` diff --git a/docs/source/turbo_stream.md b/docs/source/turbo_stream.md index b1329bb..8a9ba6f 100644 --- a/docs/source/turbo_stream.md +++ b/docs/source/turbo_stream.md @@ -34,6 +34,7 @@ Turbo Stream built-in actions are all supported in syntax `turbo_stream.xxx`: - remove - before - after +- morph ### TurboStreamResponse diff --git a/src/turbo_helper/stream.py b/src/turbo_helper/stream.py index e90a771..4b89232 100644 --- a/src/turbo_helper/stream.py +++ b/src/turbo_helper/stream.py @@ -130,6 +130,11 @@ def update(target, content=None, **kwargs): return turbo_stream.action("update", target, content, **kwargs) +@register_turbo_stream_action("morph") +def morph(target, content=None, **kwargs): + return turbo_stream.action("morph", target, content, **kwargs) + + ################################################################################ @@ -166,3 +171,8 @@ def replace_all(targets, content=None, **kwargs): @register_turbo_stream_action("update_all") def update_all(targets, content=None, **kwargs): return turbo_stream.action_all("update", targets, content, **kwargs) + + +@register_turbo_stream_action("morph_all") +def morph_all(targets, content=None, **kwargs): + return turbo_stream.action_all("morph_all", targets, content, **kwargs) diff --git a/src/turbo_helper/turbo_power.py b/src/turbo_helper/turbo_power.py index bf3434c..1e7883f 100644 --- a/src/turbo_helper/turbo_power.py +++ b/src/turbo_helper/turbo_power.py @@ -49,6 +49,25 @@ def custom_action_all(action, targets=None, content=None, **kwargs): ) +################################################################################ + +""" +When defining custom action, `target` or `targets` are both supported + +def example_action(targets=None, **attributes): + pass + +This action by default will use `targets` as the target selector + +turbo_stream.example_action("A") +Generate: ' in response.content.decode("utf-8") ) + + +class TestMorph: + def test_morph(self): + stream = '' + assert_dom_equal( + stream, turbo_stream.morph("#input", mark_safe("

Morph

")) + ) + + def test_morph_with_targets_as_positional_arg_and_html_as_kwarg(self): + stream = '' + assert_dom_equal( + stream, turbo_stream.morph_all(".test", mark_safe("

Morph

")) + ) + + def test_morph_with_additional_arguments(self): + stream = '' + assert_dom_equal( + stream, + turbo_stream.morph("#input", mark_safe("

Morph

"), something="else"), + ) diff --git a/tests/test_turbo_power.py b/tests/test_turbo_power.py index 6eec0ac..333dec8 100644 --- a/tests/test_turbo_power.py +++ b/tests/test_turbo_power.py @@ -29,40 +29,6 @@ def test_graft_with_additional_arguments(self): ) -class TestMorph: - def test_morph(self): - stream = '' - assert_dom_equal(stream, turbo_stream.morph("#input", "

Morph

")) - - def test_morph_with_targets_and_html_as_kwargs(self): - stream = '' - assert_dom_equal( - stream, turbo_stream.morph(targets="#input", html="

Morph

") - ) - - def test_morph_with_target_and_html_as_kwargs(self): - stream = '' - assert_dom_equal( - stream, turbo_stream.morph(target="input", html="

Morph

") - ) - - def test_morph_with_html_and_targets_as_kwargs(self): - stream = '' - assert_dom_equal( - stream, turbo_stream.morph(html="

Morph

", targets="#input") - ) - - def test_morph_with_targets_as_positional_arg_and_html_as_kwarg(self): - stream = '' - assert_dom_equal(stream, turbo_stream.morph("#input", html="

Morph

")) - - def test_morph_with_additional_arguments(self): - stream = '' - assert_dom_equal( - stream, turbo_stream.morph("#input", html="

Morph

", something="else") - ) - - class TestAddCssClass: def test_add_css_class(self): stream = ''