|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
| 3 | +from logging import getLogger |
3 | 4 | from pathlib import Path |
4 | 5 | from typing import TYPE_CHECKING, Any, Callable, Union, cast |
5 | 6 | from uuid import uuid4 |
|
26 | 27 |
|
27 | 28 | from reactpy.types import VdomDict |
28 | 29 |
|
| 30 | +_logger = getLogger(__name__) |
29 | 31 | DjangoForm = component_from_file( |
30 | 32 | Path(__file__).parent.parent / "static" / "reactpy_django" / "index.js", |
31 | 33 | import_names=("DjangoForm"), |
@@ -67,27 +69,34 @@ def _django_form( |
67 | 69 | @hooks.use_async_effect(dependencies=[str(submitted_data)]) |
68 | 70 | async def render_form(): |
69 | 71 | """Forms must be rendered in an async loop to allow database fields to execute.""" |
70 | | - if submitted_data: |
71 | | - await ensure_async(initialized_form.full_clean, thread_sensitive=thread_sensitive)() |
72 | | - success = not initialized_form.errors.as_data() |
73 | | - if success and on_success: |
74 | | - await ensure_async(on_success, thread_sensitive=thread_sensitive)(form_event) |
75 | | - if not success and on_error: |
76 | | - await ensure_async(on_error, thread_sensitive=thread_sensitive)(form_event) |
77 | | - if success and auto_save and isinstance(initialized_form, ModelForm): |
78 | | - await ensure_async(initialized_form.save)() |
79 | | - set_submitted_data(None) |
80 | | - |
81 | | - set_rendered_form( |
82 | | - await ensure_async(initialized_form.render)(form_template or config.REACTPY_DEFAULT_FORM_TEMPLATE) |
83 | | - ) |
| 72 | + |
| 73 | + _logger.debug(f"Rendering form with submitted data: {submitted_data}") |
| 74 | + try: |
| 75 | + if submitted_data: |
| 76 | + await ensure_async(initialized_form.full_clean, thread_sensitive=thread_sensitive)() |
| 77 | + success = not initialized_form.errors.as_data() |
| 78 | + if success and on_success: |
| 79 | + await ensure_async(on_success, thread_sensitive=thread_sensitive)(form_event) |
| 80 | + if not success and on_error: |
| 81 | + await ensure_async(on_error, thread_sensitive=thread_sensitive)(form_event) |
| 82 | + if success and auto_save and isinstance(initialized_form, ModelForm): |
| 83 | + await ensure_async(initialized_form.save)() |
| 84 | + set_submitted_data(None) |
| 85 | + |
| 86 | + set_rendered_form( |
| 87 | + await ensure_async(initialized_form.render)(form_template or config.REACTPY_DEFAULT_FORM_TEMPLATE) |
| 88 | + ) |
| 89 | + except Exception: |
| 90 | + _logger.exception("Error during form processing") |
| 91 | + |
84 | 92 |
|
85 | 93 | async def on_submit_callback(new_data: dict[str, Any]): |
86 | 94 | """Callback function provided directly to the client side listener. This is responsible for transmitting |
87 | 95 | the submitted form data to the server for processing.""" |
88 | 96 | # The client side listener passes a ReactPy Event object which needs to be |
89 | 97 | # converted to a standard dictionary. |
90 | | - convert_form_fields(dict(new_data), initialized_form) |
| 98 | + new_data = dict(new_data) |
| 99 | + convert_form_fields(new_data, initialized_form) |
91 | 100 |
|
92 | 101 | if on_receive_data: |
93 | 102 | new_form_event = FormEventData( |
|
0 commit comments