You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/src/features/hooks.md
+72-13Lines changed: 72 additions & 13 deletions
Original file line number
Diff line number
Diff line change
@@ -54,6 +54,7 @@ The function you provide into this hook must return either a `Model` or `QuerySe
54
54
| Name | Type | Description | Default |
55
55
| --- | --- | --- | --- |
56
56
| `query` | `Callable[_Params, _Result | None]` | A callable that returns a Django `Model` or `QuerySet`. | N/A |
57
+
| `options` | `QueryOptions | None` | An optional `QueryOptions` object that can modify how the query is executed. | None |
57
58
| `*args` | `_Params.args` | Positional arguments to pass into `query`. | N/A |
58
59
| `**kwargs` | `_Params.kwargs` | Keyword arguments to pass into `query`. | N/A |
59
60
@@ -67,19 +68,83 @@ The function you provide into this hook must return either a `Model` or `QuerySe
67
68
68
69
Due to Django's ORM design, database queries must be deferred using hooks. Otherwise, you will see a `SynchronousOnlyOperation` exception.
69
70
70
-
This may be resolved in a future version of Django containing an asynchronous ORM.
71
+
This compatibility may be resolved in a future version of Django containing an asynchronous ORM. However, it is still best practice to always perform ORM calls in the background via `use_query`.
71
72
72
-
??? question "Why does the example `get_items` function return a `Model` or `QuerySet`?"
73
+
??? question "Can this hook be used for things other than the Django ORM?"
73
74
74
-
This was a technical design decision to [based on Apollo](https://www.apollographql.com/docs/react/data/mutations/#usemutation-api), but ultimately helps avoid Django's `SynchronousOnlyOperation` exceptions.
75
+
If you...
75
76
76
-
The `use_query` hook ensures the provided `Model` or `QuerySet` executes all [deferred](https://docs.djangoproject.com/en/dev/ref/models/instances/#django.db.models.Model.get_deferred_fields)/[lazy queries](https://docs.djangoproject.com/en/dev/topics/db/queries/#querysets-are-lazy) safely prior to reaching your components.
77
+
1. Want to use this hook to defer IO intensive tasks to be computed in the background
78
+
2. Want to to utilize `use_query` with a different ORM
79
+
80
+
... then you can disable all postprocessing behavior by modifying the `postprocessor` parameter in `QueryOptions`.
81
+
82
+
```python
83
+
from django_idom.types import QueryOptions
84
+
from django_idom.hooks import use_query
85
+
86
+
def io_intensive_operation():
87
+
"""This is an example function call that does something IO intensive, but can
88
+
potentially fail to execute."""
89
+
...
90
+
91
+
@component
92
+
def todo_list():
93
+
query = use_query(
94
+
io_intensive_operation,
95
+
QueryOptions(
96
+
# By setting the postprocessor to a function that takes one argument
97
+
# and returns None, we can disable postprocessing behavior.
98
+
postprocessor=lambda data: None,
99
+
),
100
+
)
101
+
102
+
if query.loading or query.error:
103
+
return None
104
+
105
+
return str(query.data)
106
+
```
107
+
108
+
??? question "Can this hook automatically fetch `ManyToMany` fields or `ForeignKey` relationships?"
109
+
110
+
By default, automatic recursive fetching of `ManyToMany` or `ForeignKey` fields is disabled for performance reasons.
111
+
112
+
If you wish you enable this feature, you can modify the `postprocessor_kwargs` parameter in `QueryOptions`.
77
113
78
-
??? question "What is an "ORM"?"
114
+
```python
115
+
from example_project.my_app.models import MyModel
116
+
from django_idom.types import QueryOptions
117
+
from django_idom.hooks import use_query
118
+
119
+
def model_with_relationships():
120
+
"""This is an example function that gets `MyModel` that has a ManyToMany field, and
121
+
additionally other models that have formed a ForeignKey association to `MyModel`.
A Python **Object Relational Mapper** is an API for your code to access a database.
141
+
Please note that due Django's ORM design, the field name to access foreign keys is [always be postfixed with `_set`](https://docs.djangoproject.com/en/dev/topics/db/examples/many_to_one/).
81
142
82
-
See the [Django ORM documentation](https://docs.djangoproject.com/en/dev/topics/db/queries/) for more information.
143
+
??? question "Why does the example `get_items` function return a `Model` or `QuerySet`?"
144
+
145
+
This was a technical design decision to [based on Apollo](https://www.apollographql.com/docs/react/data/mutations/#usemutation-api), but ultimately helps avoid Django's `SynchronousOnlyOperation` exceptions.
146
+
147
+
The `use_query` hook ensures the provided `Model` or `QuerySet` executes all [deferred](https://docs.djangoproject.com/en/dev/ref/models/instances/#django.db.models.Model.get_deferred_fields)/[lazy queries](https://docs.djangoproject.com/en/dev/topics/db/queries/#querysets-are-lazy) safely prior to reaching your components.
83
148
84
149
## Use Mutation
85
150
@@ -244,12 +309,6 @@ The function you provide into this hook will have no return value.
244
309
245
310
However, even when resolved it is best practice to perform ORM queries within the `use_query` in order to handle `loading` and `error` states.
246
311
247
-
??? question "What is an "ORM"?"
248
-
249
-
A Python **Object Relational Mapper** is an API for your code to access a database.
250
-
251
-
See the [Django ORM documentation](https://docs.djangoproject.com/en/dev/topics/db/queries/) for more information.
252
-
253
312
## Use Websocket
254
313
255
314
You can fetch the Django Channels [websocket](https://channels.readthedocs.io/en/stable/topics/consumers.html#asyncjsonwebsocketconsumer) at any time by using `use_websocket`.
0 commit comments