Skip to content

Commit

Permalink
Merge pull request #569 from iommirocks/nested-forms-save-edit-table
Browse files Browse the repository at this point in the history
Nested forms save post handler should also save EditTables
  • Loading branch information
jlubcke authored Aug 28, 2024
2 parents 656c69f + b14a81c commit b1bfa38
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 8 deletions.
4 changes: 2 additions & 2 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 48 additions & 6 deletions docs/test_doc_cookbook_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
)
from iommi.form import save_nested_forms
from iommi.struct import Struct
from iommi.traversable import build_long_path
from tests.helpers import (
req,
show_output,
Expand Down Expand Up @@ -804,32 +805,73 @@ def test_form_with_m2m_key_reverse(small_discography):
# @end


def test_nested_forms(small_discography):
def test_nested_forms(medium_discography):
# language=rst
"""
How do I nest multiple forms?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You need to use the `save_nested_forms` post handler to have a single save button for all the nested forms and `EditTable`s:
"""

class MyNestedForm(Form):
edit_dio = Form.edit(auto__instance=Artist.objects.get(name='Black Sabbath'))
edit_ozzy = Form.edit(
auto__model=Artist,
instance=lambda **_: Artist.objects.get(name='Ozzy Osbourne'),
)
create_artist = Form.create(auto__model=Artist)
create_album = Form.create(auto__model=Album)
edit_albums = EditTable(
auto__model=Album,
auto__include=['name', 'year'],
columns__name__field__include=True,
)

class Meta:
actions__submit__post_handler = save_nested_forms

# @test
ozzy_pk = Artist.objects.get(name='Ozzy Osbourne').pk

form = MyNestedForm().bind(request=req('get'))

assert list(form.nested_forms.keys()) == ['edit_dio', 'create_artist', 'create_album']
assert list(form.nested_forms.keys()) == [
'edit_ozzy',
'create_artist',
# EditTable stuff
'bulk',
'edit_form',
'create_form',
'edit_albums',
]

show_output(form)

album1, album2, album3 = Album.objects.all()

updates = {
'-submit': '',
'name': 'Ozzy-updated',
'create_artist/name': 'Dio-created',
f'edit_albums/name/{album1.pk}': 'Name 1',
f'edit_albums/name/{album2.pk}': 'Name 2',
f'edit_albums/name/{album3.pk}': 'Name 3',
}

form = MyNestedForm().bind(request=req(
'post',
**updates,
))
assert not form.get_errors()
form.render_to_response()

assert Artist.objects.get(pk=ozzy_pk).name == 'Ozzy-updated'
assert Artist.objects.get(name='Dio-created')
album1.refresh_from_db()
assert album1.name == 'Name 1'
# @end


def test_fields_template(album):
heaven_and_hell = album
# language=rst
"""
.. _Form.fields_template:
Expand Down Expand Up @@ -861,7 +903,7 @@ class Meta:
name = Field()
email = Field()
comment = Field.textarea()
album = Field.hardcoded(initial=heaven_and_hell)
album = Field.hardcoded(initial=lambda **_: Album.objects.get(name='Heaven & Hell'))

# @test
form = CommentForm().bind(request=req('get'))
Expand Down
7 changes: 7 additions & 0 deletions iommi/form.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,13 @@ def save_nested_forms(form, request, **_):
if action.post_handler and action.invoke_callback(action.post_handler) is None:
did_fail = True

# Handle EditTables
for action in getattr(nested_form, 'edit_actions', {}).values():
if action.post_handler is None:
continue
if action.post_handler and action.invoke_callback(action.post_handler) is None:
did_fail = True

if not did_fail:
if 'post_save' in form.extra:
form.invoke_callback(form.extra.post_save)
Expand Down

0 comments on commit b1bfa38

Please sign in to comment.