-
-
Notifications
You must be signed in to change notification settings - Fork 22
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
use_query
prefetching for ManyToMany and ManyToOne fields
#112
Conversation
@rmorshea This may not be possible. I think the solution may be documenting that |
On a side note, I'm observing the following traceback. It seems like Traceback (most recent call last):
File "/home/ryan/Repositories/idom-team/django-idom/venv/lib/python3.10/site-packages/asgiref/sync.py", line 472, in thread_handler
raise exc_info[1]
File "/home/ryan/Repositories/idom-team/django-idom/venv/lib/python3.10/site-packages/django/core/handlers/exception.py", line 42, in inner
response = await get_response(request)
File "/home/ryan/Repositories/idom-team/django-idom/venv/lib/python3.10/site-packages/django/core/handlers/base.py", line 253, in _get_response_async
response = await wrapped_callback(
File "/home/ryan/Repositories/idom-team/django-idom/src/django_idom/http/views.py", line 52, in view_to_component_iframe
response["X-Frame-Options"] = "SAMEORIGIN"
TypeError: 'coroutine' object does not support item assignment |
Weird, I haven't seen that in my testing environment. Not happening on GH actions either. We'll have to narrow that one down, might be OS-dependent? |
I needed to add a kwarg to allow users to turn off Is |
use_query
prefetching for ManyToMany and ManyToOne fields
Unfortunately, Here's one way we could work around this... Instead of implementing this caching logic in # default prefetches fields
use_query(prefetch(my_query), *args, **kwargs)
# prefetch related too
use_query(prefetch(my_query, related=True), *args, **kwargs) Where P = ParamSpec("P")
R = TypeVar("R")
def prefetch(query: Callable[P, R], fields: bool = True, related: bool = False) -> Callable[P, R]: ... I actually quite like this since it doesn't impinge on the |
I just realized that @prefetch
def my_query(): ...
@prefetch(related=True)
def my_query(): ... |
Some form of prefetching would still need to occur within I personally think it feels the least awkward for them to be parameters within |
Having it be a decorator is also kind of unfortunate, since I was hoping the default behavior would be to prefetch. Now that I'm thinking about it, it's not unrealistic to ask Django users to add a Downside is they would have to add this parameter for every model they want prefetching behaviors in. |
The type hints for from typing import ParamSpec, TypeVar, overload
_Params = ParamSpec("_Params")
_Result = TypeVar("_Result")
@overload
def prefetch(
query: None = ..., *, fields: bool = ..., related: bool = ...
) -> Callable[[Callable[_Params, _Result]], Callable[_Params, _Result]]:
...
@overload
def prefetch(
query: Callable[_Params, _Result], *, fields: bool = ..., related: bool = ...
) -> Callable[_Params, _Result]:
...
def prefetch(
query: Callable[_Params, _Result] | None = None, *, fields: bool = True, related: bool = False
) -> Callable[_Params, _Result] | Callable[[Callable[_Params, _Result]], Callable[_Params, _Result]]:
def wrapper(query: Callable[_Params, _Result]) -> Callable[_Params, _Result]:
...
if query is None:
return wrapper
else:
return wrapper(query) This allows prefetch to be used as a decorator and with an inline call. |
I attempted to generate an option that is extensible, with the knowledge that |
I think I'd like to have some more discussion before implementing anything. I've gathered relevant issues that require discussion into a meta-issue: #113 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can merge this as-is. However, when it comes time to get this into core I'd like to completely rethink the API. In doing so, I think the user experience can be greatly improved.
How would you feel about defaulting I think it's better to have things "just work" by default, and then have users turn it off if performance becomes an issue. I would imagine the vast majority of Django users don't have deeply nested trees of data. |
Having that be the default seems alright. |
Do you want to review the docs or should I merge? |
Besides that one little nit it looks good. |
a57816e
to
e4f299d
Compare
Since the changes are non-trivial, I will wait for one more approval. |
e4f299d
to
0128169
Compare
…value for postprocessor
0128169
to
17de270
Compare
Pushing this forward, we can do any requested changes in the version bump PR. |
Description
Attempt at auto fetching ManyToMany fields
Checklist:
Please update this checklist as you complete each item:
changelog.rst
has been updated with any significant changes, if necessary.