Skip to content

Commit

Permalink
Add thread_sensitive arg to ensure_async func
Browse files Browse the repository at this point in the history
  • Loading branch information
Archmonger committed Dec 10, 2024
1 parent e32fc67 commit 3ed84db
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 10 deletions.
3 changes: 2 additions & 1 deletion docs/src/reference/components.md
Original file line number Diff line number Diff line change
Expand Up @@ -409,11 +409,12 @@ Compatible with both [standard Django forms](https://docs.djangoproject.com/en/s
| `#!python on_success` | `#!python AsyncFormEvent | SyncFormEvent | None` | A callback function that is called when the form is successfully submitted. | `#!python None` |
| `#!python on_error` | `#!python AsyncFormEvent | SyncFormEvent | None` | A callback function that is called when the form submission fails. | `#!python None` |
| `#!python on_receive_data` | `#!python AsyncFormEvent | SyncFormEvent | None` | A callback function that is called before newly submitted form data is rendered. | `#!python None` |
| `#!python on_change` | `#!python AsyncFormEvent | SyncFormEvent | None` | A callback function that is called when the form is changed. | `#!python None` |
| `#!python on_change` | `#!python AsyncFormEvent | SyncFormEvent | None` | A callback function that is called when a form field is modified by the user. | `#!python None` |
| `#!python auto_save` | `#!python bool` | If `#!python True`, the form will automatically call `#!python save` on successful submission of a `#!python ModelForm`. This has no effect on regular `#!python Form` instances. | `#!python True` |
| `#!python extra_props` | `#!python dict[str, Any] | None` | Additional properties to add to the `#!html <form>` element. | `#!python None` |
| `#!python extra_transforms` | `#!python Sequence[Callable[[VdomDict], Any]] | None` | A list of functions that transforms the newly generated VDOM. The functions will be repeatedly called on each VDOM node. | `#!python None` |
| `#!python form_template` | `#!python str | None` | The template to use for the form. If `#!python None`, Django's default template is used. | `#!python None` |
| `#!python thread_sensitive` | `#!python bool` | Whether to run event callback functions in thread sensitive mode. This mode only applies to sync functions, and is turned on by default due to Django ORM limitations. | `#!python True` |
| `#!python top_children` | `#!python Sequence[Any]` | Additional elements to add to the top of the form. | `#!python tuple` |
| `#!python bottom_children` | `#!python Sequence[Any]` | Additional elements to add to the bottom of the form. | `#!python tuple` |
| `#!python key` | `#!python Key | None` | A key to uniquely identify this component which is unique amongst a component's immediate siblings. | `#!python None` |
Expand Down
4 changes: 2 additions & 2 deletions docs/src/reference/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Query functions can be sync or async.
| --- | --- | --- | --- |
| `#!python query` | `#!python Callable[FuncParams, Awaitable[Inferred]] | Callable[FuncParams, Inferred]` | A function that executes a query and returns some data. | N/A |
| `#!python kwargs` | `#!python dict[str, Any] | None` | Keyword arguments to passed into the `#!python query` function. | `#!python None` |
| `#!python thread_sensitive` | `#!python bool` | Whether to run your query function in thread sensitive mode. This mode only applies to sync query functions, and is turned on by default due to Django ORM limitations. | `#!python True` |
| `#!python thread_sensitive` | `#!python bool` | Whether to run your query function in thread sensitive mode. This setting only applies to sync functions, and is turned on by default due to Django ORM limitations. | `#!python True` |
| `#!python postprocessor` | `#!python AsyncPostprocessor | SyncPostprocessor | None` | A callable that processes the query `#!python data` before it is returned. The first argument of postprocessor function must be the query `#!python data`. All proceeding arguments are optional `#!python postprocessor_kwargs`. This postprocessor function must return the modified `#!python data`. | `#!python None` |
| `#!python postprocessor_kwargs` | `#!python dict[str, Any] | None` | Keyworded arguments passed into the `#!python postprocessor` function. | `#!python None` |

Expand Down Expand Up @@ -188,7 +188,7 @@ Mutation functions can be sync or async.
| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `#!python mutation` | `#!python Callable[FuncParams, bool | None] | Callable[FuncParams, Awaitable[bool | None]]` | A callable that performs Django ORM create, update, or delete functionality. If this function returns `#!python False`, then your `#!python refetch` function will not be used. | N/A |
| `#!python thread_sensitive` | `#!python bool` | Whether to run the mutation in thread sensitive mode. This mode only applies to sync mutation functions, and is turned on by default due to Django ORM limitations. | `#!python True` |
| `#!python thread_sensitive` | `#!python bool` | Whether to run the mutation in thread sensitive mode. This setting only applies to sync functions, and is turned on by default due to Django ORM limitations. | `#!python True` |
| `#!python refetch` | `#!python Callable[..., Any] | Sequence[Callable[..., Any]] | None` | A query function (the function you provide to your `#!python use_query` hook) or a sequence of query functions that need a `#!python refetch` if the mutation succeeds. This is useful for refreshing data after a mutation has been performed. | `#!python None` |

<font size="4">**Returns**</font>
Expand Down
7 changes: 6 additions & 1 deletion src/reactpy_django/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ def django_form(
extra_props: dict[str, Any] | None = None,
extra_transforms: Sequence[Callable[[VdomDict], Any]] | None = None,
form_template: str | None = None,
thread_sensitive: bool = True,
top_children: Sequence[Any] = (),
bottom_children: Sequence[Any] = (),
key: Key | None = None,
Expand All @@ -144,13 +145,16 @@ def django_form(
on_success: A callback function that is called when the form is successfully submitted.
on_error: A callback function that is called when the form submission fails.
on_receive_data: A callback function that is called before newly submitted form data is rendered.
on_change: A callback function that is called when the form is changed.
on_change: A callback function that is called when a form field is modified by the user.
auto_save: If `True`, the form will automatically call `save` on successful submission of \
a `ModelForm`. This has no effect on regular `Form` instances.
extra_props: Additional properties to add to the `html.form` element.
extra_transforms: A list of functions that transforms the newly generated VDOM. \
The functions will be repeatedly called on each VDOM node.
form_template: The template to use for the form. If `None`, Django's default template is used.
thread_sensitive: Whether to run event callback functions in thread sensitive mode. \
This mode only applies to sync functions, and is turned on by default due to Django \
ORM limitations.
top_children: Additional elements to add to the top of the form.
bottom_children: Additional elements to add to the bottom of the form.
key: A key to uniquely identify this component which is unique amongst a component's \
Expand All @@ -167,6 +171,7 @@ def django_form(
extra_props=extra_props or {},
extra_transforms=extra_transforms or [],
form_template=form_template,
thread_sensitive=thread_sensitive,
top_children=top_children,
bottom_children=bottom_children,
key=key,
Expand Down
9 changes: 5 additions & 4 deletions src/reactpy_django/forms/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def _django_form(
extra_props: dict,
extra_transforms: Sequence[Callable[[VdomDict], Any]],
form_template: str | None,
thread_sensitive: bool,
top_children: Sequence,
bottom_children: Sequence,
):
Expand Down Expand Up @@ -80,9 +81,9 @@ async def render_form():
await database_sync_to_async(initialized_form.full_clean)()
success = not initialized_form.errors.as_data()
if success and on_success:
await ensure_async(on_success)(form_event)
await ensure_async(on_success, thread_sensitive=thread_sensitive)(form_event)
if not success and on_error:
await ensure_async(on_error)(form_event)
await ensure_async(on_error, thread_sensitive=thread_sensitive)(form_event)
if success and auto_save and isinstance(initialized_form, ModelForm):
await database_sync_to_async(initialized_form.save)()
set_submitted_data(None)
Expand All @@ -103,15 +104,15 @@ async def on_submit_callback(new_data: dict[str, Any]):
new_form_event = FormEventData(
form=initialized_form, submitted_data=new_data, set_submitted_data=set_submitted_data
)
await ensure_async(on_receive_data)(new_form_event)
await ensure_async(on_receive_data, thread_sensitive=thread_sensitive)(new_form_event)

if submitted_data != new_data:
set_submitted_data(new_data)

async def _on_change(_event):
"""Event that exist solely to allow the user to detect form changes."""
if on_change:
await ensure_async(on_change)(form_event)
await ensure_async(on_change, thread_sensitive=thread_sensitive)(form_event)

if not rendered_form:
return None
Expand Down
4 changes: 2 additions & 2 deletions src/reactpy_django/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def use_query(
Kwargs:
kwargs: Keyword arguments to passed into the `query` function.
thread_sensitive: Whether to run the query in thread sensitive mode. \
This mode only applies to sync query functions, and is turned on by default \
This setting only applies to sync functions, and is turned on by default \
due to Django ORM limitations.
postprocessor: A callable that processes the query `data` before it is returned. \
The first argument of postprocessor function must be the query `data`. All \
Expand Down Expand Up @@ -219,7 +219,7 @@ def use_mutation(
Kwargs:
thread_sensitive: Whether to run the mutation in thread sensitive mode. \
This mode only applies to sync mutation functions, and is turned on by default \
This setting only applies to sync functions, and is turned on by default \
due to Django ORM limitations.
refetch: A query function (the function you provide to your `use_query` \
hook) or a sequence of query functions that need a `refetch` if the \
Expand Down
4 changes: 4 additions & 0 deletions src/reactpy_django/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from concurrent.futures import ThreadPoolExecutor
from copy import deepcopy
from fnmatch import fnmatch
from functools import wraps
from importlib import import_module
from pathlib import Path
from typing import TYPE_CHECKING, Any, Awaitable, Callable
Expand Down Expand Up @@ -47,6 +48,9 @@
from django.views import View
from reactpy.types import ComponentConstructor

from reactpy_django.types import FuncParams, Inferred


_logger = logging.getLogger(__name__)
_TAG_PATTERN = r"(?P<tag>component)"
_PATH_PATTERN = r"""(?P<path>"[^"'\s]+"|'[^"'\s]+')"""
Expand Down

0 comments on commit 3ed84db

Please sign in to comment.