Skip to content

Commit 0d6c1a7

Browse files
authored
use_query prefetching for ManyToMany and ManyToOne fields (#112)
1 parent d7f6f93 commit 0d6c1a7

27 files changed

+618
-120
lines changed

.github/pull_request_template.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ A summary of the changes.
77
Please update this checklist as you complete each item:
88

99
- [ ] Tests have been included for all bug fixes or added functionality.
10-
- [ ] The `changelog.rst` has been updated with any significant changes, if necessary.
10+
- [ ] The changelog has been updated with any significant changes, if necessary.
1111
- [ ] GitHub Issues which may be closed by this PR have been linked.

.github/workflows/test-docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ jobs:
2222
python-version: 3.x
2323
- run: pip install -r requirements/build-docs.txt
2424
- run: linkcheckMarkdown docs/ -v -r
25-
- run: mkdocs build --verbose --strict
25+
- run: mkdocs build --strict

CHANGELOG.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,17 @@ Using the following categories, list your changes in this order:
2222

2323
## [Unreleased]
2424

25-
- Nothing (yet)
25+
### Added
26+
27+
- Add `options: QueryOptions` parameter to `use_query` to allow for configuration of this hook.
28+
29+
### Changed
30+
31+
- By default, `use_query` will recursively prefetch all many-to-many or many-to-one relationships to prevent `SynchronousOnlyOperation` exceptions.
32+
33+
### Removed
34+
35+
- `django_idom.hooks._fetch_lazy_fields` has been deleted. The equivalent replacement is `django_idom.utils.django_query_postprocessor`.
2636

2737
## [2.1.0] - 2022-11-01
2838

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ You will need a file to define your [IDOM](https://github.com/idom-team/idom) co
3030
<!--py-header-end-->
3131
<!--py-code-start-->
3232

33-
```python linenums="1"
33+
```python
3434
from idom import component, html
3535

3636
@component
@@ -51,7 +51,7 @@ Additionally, you can pass in keyword arguments into your component function. Fo
5151
<!--html-header-end-->
5252
<!--html-code-start-->
5353

54-
```jinja linenums="1"
54+
```jinja
5555
{% load idom %}
5656
<!DOCTYPE html>
5757
<html>

docs/includes/examples.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!--todo-model-start-->
22

3-
```python linenums="1"
3+
```python
44
from django.db import models
55

66
class TodoItem(models.Model):

docs/includes/orm.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!--orm-excp-start-->
2+
3+
Due to Django's ORM design, database queries must be deferred using hooks. Otherwise, you will see a `SynchronousOnlyOperation` exception.
4+
5+
These `SynchronousOnlyOperation` exceptions may be resolved in a future version of Django containing an asynchronous ORM. However, it is best practice to always perform ORM calls in the background via hooks.
6+
7+
<!--orm-excp-end-->
8+
9+
<!--orm-fetch-start-->
10+
11+
By default, automatic recursive fetching of `ManyToMany` or `ForeignKey` fields is enabled within the default `QueryOptions.postprocessor`. This is needed to prevent `SynchronousOnlyOperation` exceptions when accessing these fields within your IDOM components.
12+
13+
<!--orm-fetch-end-->

docs/src/dictionary.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ changelog
66
async
77
pre
88
prefetch
9+
prefetching
910
preloader
1011
whitespace
1112
refetch
@@ -22,3 +23,5 @@ unstyled
2223
py
2324
idom
2425
asgi
26+
postfixed
27+
postprocessing

docs/src/features/components.md

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Convert any Django view into a IDOM component by using this decorator. Compatibl
88

99
=== "components.py"
1010

11-
```python linenums="1"
11+
```python
1212
from idom import component, html
1313
from django.http import HttpResponse
1414
from django_idom.components import view_to_component
@@ -39,7 +39,7 @@ Convert any Django view into a IDOM component by using this decorator. Compatibl
3939

4040
| Type | Description |
4141
| --- | --- |
42-
| `_ViewComponentConstructor` | A function that takes `request: HttpRequest | None, *args: Any, key: Key | None, **kwargs: Any` and returns an IDOM component. |
42+
| `_ViewComponentConstructor` | A function that takes `request, *args, key, **kwargs` and returns an IDOM component. All parameters are directly provided to your view, besides `key` which is used by IDOM. |
4343

4444
??? Warning "Potential information exposure when using `compatibility = True`"
4545

@@ -88,7 +88,7 @@ Convert any Django view into a IDOM component by using this decorator. Compatibl
8888

8989
=== "components.py"
9090

91-
```python linenums="1"
91+
```python
9292
from idom import component, html
9393
from django.http import HttpResponse
9494
from django.views import View
@@ -112,7 +112,7 @@ Convert any Django view into a IDOM component by using this decorator. Compatibl
112112

113113
=== "components.py"
114114

115-
```python linenums="1"
115+
```python
116116
from idom import component, html
117117
from django.http import HttpResponse
118118
from django_idom.components import view_to_component
@@ -135,7 +135,7 @@ Convert any Django view into a IDOM component by using this decorator. Compatibl
135135

136136
=== "components.py"
137137

138-
```python linenums="1"
138+
```python
139139
from idom import component, html
140140
from django.http import HttpResponse, HttpRequest
141141
from django_idom.components import view_to_component
@@ -164,7 +164,7 @@ Convert any Django view into a IDOM component by using this decorator. Compatibl
164164

165165
=== "components.py"
166166

167-
```python linenums="1"
167+
```python
168168
from idom import component, html
169169
from django.http import HttpResponse
170170
from django_idom.components import view_to_component
@@ -196,11 +196,9 @@ Convert any Django view into a IDOM component by using this decorator. Compatibl
196196

197197
In these scenarios, you may want to rely on best-fit parsing by setting the `strict_parsing` parameter to `False`.
198198

199-
Note that best-fit parsing is designed to be similar to how web browsers would handle non-standard or broken HTML.
200-
201199
=== "components.py"
202200

203-
```python linenums="1"
201+
```python
204202
from idom import component, html
205203
from django.http import HttpResponse
206204
from django_idom.components import view_to_component
@@ -216,7 +214,7 @@ Convert any Django view into a IDOM component by using this decorator. Compatibl
216214
)
217215
```
218216

219-
217+
_Note: Best-fit parsing is designed to be similar to how web browsers would handle non-standard or broken HTML._
220218

221219
---
222220

@@ -226,11 +224,11 @@ Convert any Django view into a IDOM component by using this decorator. Compatibl
226224

227225
Any view can be rendered within compatibility mode. However, the `transforms`, `strict_parsing`, `request`, `args`, and `kwargs` arguments do not apply to compatibility mode.
228226

229-
Please note that by default the iframe is unstyled, and thus won't look pretty until you add some CSS.
227+
230228

231229
=== "components.py"
232230

233-
```python linenums="1"
231+
```python
234232
from idom import component, html
235233
from django.http import HttpResponse
236234
from django_idom.components import view_to_component
@@ -246,6 +244,8 @@ Convert any Django view into a IDOM component by using this decorator. Compatibl
246244
)
247245
```
248246

247+
_Note: By default the `compatibility` iframe is unstyled, and thus won't look pretty until you add some CSS._
248+
249249
---
250250

251251
<font size="4">**`transforms`**</font>
@@ -258,7 +258,7 @@ Convert any Django view into a IDOM component by using this decorator. Compatibl
258258

259259
=== "components.py"
260260

261-
```python linenums="1"
261+
```python
262262
from idom import component, html
263263
from django.http import HttpResponse
264264
from django_idom.components import view_to_component
@@ -285,7 +285,7 @@ Allows you to defer loading a CSS stylesheet until a component begins rendering.
285285

286286
=== "components.py"
287287

288-
```python linenums="1"
288+
```python
289289
from idom import component, html
290290
from django_idom.components import django_css
291291

@@ -322,7 +322,7 @@ Allows you to defer loading a CSS stylesheet until a component begins rendering.
322322

323323
Here's an example on what you should avoid doing for Django static files:
324324

325-
```python linenums="1"
325+
```python
326326
from idom import component, html
327327
from django.templatetags.static import static
328328

@@ -340,7 +340,7 @@ Allows you to defer loading a CSS stylesheet until a component begins rendering.
340340

341341
For external CSS, substitute `django_css` with `html.link`.
342342

343-
```python linenums="1"
343+
```python
344344
from idom import component, html
345345

346346
@component
@@ -363,7 +363,7 @@ Allows you to defer loading JavaScript until a component begins rendering. This
363363

364364
=== "components.py"
365365

366-
```python linenums="1"
366+
```python
367367
from idom import component, html
368368
from django_idom.components import django_js
369369

@@ -400,7 +400,7 @@ Allows you to defer loading JavaScript until a component begins rendering. This
400400

401401
Here's an example on what you should avoid doing for Django static files:
402402

403-
```python linenums="1"
403+
```python
404404
from idom import component, html
405405
from django.templatetags.static import static
406406

@@ -418,7 +418,7 @@ Allows you to defer loading JavaScript until a component begins rendering. This
418418

419419
For external JavaScript, substitute `django_js` with `html.script`.
420420

421-
```python linenums="1"
421+
```python
422422
from idom import component, html
423423

424424
@component

docs/src/features/decorators.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ This decorator can be used with or without parentheses.
1414

1515
=== "components.py"
1616

17-
```python linenums="1"
17+
```python
1818
from django_idom.decorators import auth_required
1919
from django_idom.hooks import use_websocket
2020
from idom import component, html
@@ -48,7 +48,7 @@ This decorator can be used with or without parentheses.
4848

4949
=== "components.py"
5050

51-
```python linenums="1"
51+
```python
5252
from django_idom.decorators import auth_required
5353
from idom import component, html
5454

@@ -68,7 +68,7 @@ This decorator can be used with or without parentheses.
6868

6969
=== "components.py"
7070

71-
```python linenums="1"
71+
```python
7272
from django_idom.decorators import auth_required
7373
from django_idom.hooks import use_websocket
7474
from idom import component, html
@@ -85,7 +85,7 @@ This decorator can be used with or without parentheses.
8585

8686
=== "components.py"
8787

88-
```python linenums="1"
88+
```python
8989
from django_idom.decorators import auth_required
9090
from django_idom.hooks import use_websocket
9191
from idom import component, html
@@ -105,7 +105,7 @@ This decorator can be used with or without parentheses.
105105

106106
=== "models.py"
107107

108-
```python linenums="1"
108+
```python
109109
from django.contrib.auth.models import AbstractBaseUser
110110

111111
class CustomUserModel(AbstractBaseUser):
@@ -118,7 +118,7 @@ This decorator can be used with or without parentheses.
118118

119119
=== "components.py"
120120

121-
```python linenums="1"
121+
```python
122122
from django_idom.decorators import auth_required
123123
from django_idom.hooks import use_websocket
124124
from idom import component, html

0 commit comments

Comments
 (0)