Skip to content

use_query prefetching for ManyToMany and ManyToOne fields #112

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
84b6fb3
Attempt ManyToMany auto-fetching
Archmonger Nov 15, 2022
8904fd3
functioning many_to_many and many_to_one handling
Archmonger Nov 15, 2022
11b185e
better naming for todo item functions
Archmonger Nov 15, 2022
cdfacbe
fetch_options decorator
Archmonger Nov 16, 2022
e6b1237
failure tests
Archmonger Nov 16, 2022
0564716
format migrations
Archmonger Nov 16, 2022
36035fb
OrmFetch type hint on fetch_options
Archmonger Nov 16, 2022
ecb96e6
pass -> ...
Archmonger Nov 16, 2022
d1bd3f8
better variable/function names
Archmonger Nov 17, 2022
96c451f
set fetch attributes to false by default
Archmonger Nov 17, 2022
2b8d036
remove kw_only for py3.8 compatibility
Archmonger Nov 17, 2022
f73c6d9
prep _postprocess_django_query for potential API changes
Archmonger Nov 17, 2022
9259729
QueryOptions is Callable
Archmonger Nov 17, 2022
50de9c4
one test case without query_options
Archmonger Nov 17, 2022
99ac352
use_query options via type hints
Archmonger Nov 18, 2022
8bf6097
fix mypy warnings
Archmonger Nov 18, 2022
b1e55c9
Merge remote-tracking branch 'upstream/main' into use-query-manager-f…
Archmonger Nov 18, 2022
8aeef17
cleanup
Archmonger Nov 30, 2022
275c385
fix docs builds
Archmonger Nov 30, 2022
b0e2c03
better postprocessor description
Archmonger Nov 30, 2022
31c1998
remove unneeded defaults for postprocessor opts
Archmonger Dec 8, 2022
35e2d3f
postprocessor options as kwargs
Archmonger Dec 8, 2022
a88bee4
add tests for relational query
Archmonger Dec 9, 2022
93f918a
documentation
Archmonger Dec 9, 2022
17c5bd8
grammar correction
Archmonger Dec 9, 2022
a17ca7c
use_query docs
Archmonger Dec 11, 2022
834a536
move queryoptions to first arg
Archmonger Dec 11, 2022
4865e1d
fix tests
Archmonger Dec 11, 2022
10ddb70
add linenums to docs
Archmonger Dec 11, 2022
794e15e
enable linenums globally
Archmonger Dec 11, 2022
3f082fc
add changelog
Archmonger Dec 12, 2022
1baa379
misc docs cleanup
Archmonger Dec 12, 2022
b0043b1
changelog is not an rst
Archmonger Dec 12, 2022
03c0681
revert data variable name
Archmonger Dec 12, 2022
17de270
Typehints, Postprocessor returns `Any`, and `defaults` configuration …
Archmonger Dec 15, 2022
efabc16
reorganize config.py
Archmonger Dec 15, 2022
a1b8f6e
custom postprocessor docs
Archmonger Dec 28, 2022
f5ccda1
fix spelling issues
Archmonger Dec 28, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ A summary of the changes.
Please update this checklist as you complete each item:

- [ ] Tests have been included for all bug fixes or added functionality.
- [ ] The `changelog.rst` has been updated with any significant changes, if necessary.
- [ ] The changelog has been updated with any significant changes, if necessary.
- [ ] GitHub Issues which may be closed by this PR have been linked.
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,17 @@ Using the following categories, list your changes in this order:

## [Unreleased]

- Nothing (yet)
### Added

- Add `options: QueryOptions` parameter to `use_query` to allow for configuration of this hook.

### Changed

- By default, `use_query` will recursively prefetch all many-to-many or many-to-one relationships to prevent `SynchronousOnlyOperation` exceptions.

### Removed

- `django_idom.hooks._fetch_lazy_fields` has been deleted. The equivalent replacement is `django_idom.utils.django_query_postprocessor`.

## [2.1.0] - 2022-11-01

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ You will need a file to define your [IDOM](https://github.com/idom-team/idom) co
<!--py-header-end-->
<!--py-code-start-->

```python linenums="1"
```python
from idom import component, html

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

```jinja linenums="1"
```jinja
{% load idom %}
<!DOCTYPE html>
<html>
Expand Down
2 changes: 1 addition & 1 deletion docs/includes/examples.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!--todo-model-start-->

```python linenums="1"
```python
from django.db import models

class TodoItem(models.Model):
Expand Down
13 changes: 13 additions & 0 deletions docs/includes/orm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!--orm-excp-start-->

Due to Django's ORM design, database queries must be deferred using hooks. Otherwise, you will see a `SynchronousOnlyOperation` exception.

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.

<!--orm-excp-end-->

<!--orm-fetch-start-->

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.

<!--orm-fetch-end-->
3 changes: 3 additions & 0 deletions docs/src/dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ changelog
async
pre
prefetch
prefetching
preloader
whitespace
refetch
Expand All @@ -22,3 +23,5 @@ unstyled
py
idom
asgi
postfixed
postprocessing
38 changes: 19 additions & 19 deletions docs/src/features/components.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Convert any Django view into a IDOM component by using this decorator. Compatibl

=== "components.py"

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

| Type | Description |
| --- | --- |
| `_ViewComponentConstructor` | A function that takes `request: HttpRequest | None, *args: Any, key: Key | None, **kwargs: Any` and returns an IDOM component. |
| `_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. |

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

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

=== "components.py"

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

=== "components.py"

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

=== "components.py"

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

=== "components.py"

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

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

Note that best-fit parsing is designed to be similar to how web browsers would handle non-standard or broken HTML.

=== "components.py"

```python linenums="1"
```python
from idom import component, html
from django.http import HttpResponse
from django_idom.components import view_to_component
Expand All @@ -216,7 +214,7 @@ Convert any Django view into a IDOM component by using this decorator. Compatibl
)
```


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

---

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

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

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


=== "components.py"

```python linenums="1"
```python
from idom import component, html
from django.http import HttpResponse
from django_idom.components import view_to_component
Expand All @@ -246,6 +244,8 @@ Convert any Django view into a IDOM component by using this decorator. Compatibl
)
```

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

---

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

=== "components.py"

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

=== "components.py"

```python linenums="1"
```python
from idom import component, html
from django_idom.components import django_css

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

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

```python linenums="1"
```python
from idom import component, html
from django.templatetags.static import static

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

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

```python linenums="1"
```python
from idom import component, html

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

=== "components.py"

```python linenums="1"
```python
from idom import component, html
from django_idom.components import django_js

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

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

```python linenums="1"
```python
from idom import component, html
from django.templatetags.static import static

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

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

```python linenums="1"
```python
from idom import component, html

@component
Expand Down
12 changes: 6 additions & 6 deletions docs/src/features/decorators.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ This decorator can be used with or without parentheses.

=== "components.py"

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

=== "components.py"

```python linenums="1"
```python
from django_idom.decorators import auth_required
from idom import component, html

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

=== "components.py"

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

=== "components.py"

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

=== "models.py"

```python linenums="1"
```python
from django.contrib.auth.models import AbstractBaseUser

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

=== "components.py"

```python linenums="1"
```python
from django_idom.decorators import auth_required
from django_idom.hooks import use_websocket
from idom import component, html
Expand Down
Loading