-
-
Notifications
You must be signed in to change notification settings - Fork 22
Allow Django ORM usage within components #80
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
Conversation
Archmonger
commented
Jun 26, 2022
•
edited
Loading
edited
- Django ORM does not work well with IDOM #79
While I understand the aversion towards loading things from the database in effects, this is actually very common and generally recommend in React. That's because you don't want to block rendering while you're reading data, and you want to keep side effects like writing data to the database, inside a Typically, the way people handle this in react is to create a hook like this data, loading, error = use_query(query)
if loading:
return loading_spinner()
if error:
return error_message(error)
return the_actual_view(data) Where the implementation of def use_query(query):
data, set_data = use_state(None)
loading, set_loading = use_state(True)
error, set_error = use_state(None)
@use_effect
async def load_data():
set_loading(True)
try:
set_data(fetch_from_database(query)
except Exception as error:
set_error(error)
finally:
set_loading(False)
return data, loading, error An example of such a hook can be found in the popular GraphQL client Apollo. My recommendation would be to create a hooks that functions in a similar way to those from Apollo (i.e |
I believe the For example, in Conreq's circumstance, there's a lot of situations where I'm absolutely reliant on ORM queries for each render. Having it built into the component vastly simplifies the design. Also, frankly, the Django ORM doesn't work well in effects either due to similar protection schemas. |
I guess I understand that. However, given that loading and mutating database resources should generally be done in effects, we ought to give people an easier way to do that since it's tedious to write out the loading/error/success states every time you need to access the DB in a component. |
The Django ORM doesn't work well in effects either due to similar protection schemas. Also, I'm about 80% certain we can't wrap the Django ORM in a There is a chance Django 4.1 will help reduce limitations enough for |
Ok, I don't think I understood the issue here. The fact that we're running in an event loop at all makes Django unhappy. Would something like this work to avoid the @component
def sample():
@use_effect
@async_to_sync # <-- I'm thinking that this might make Django happy in the thread_sensitive=True mode?
async def do_orm_work():
Model.objects.all()
... |
I haven't tested the decorator directly on the effect, but it certainly does work when used inside the effect. |
Also, is it the case that the data, loading, error = use_query(Model.objects.all()) Inside |
I will need to double check at what point during execution the exception is raised. I will get back to you on that. |
And, if the exception is caused when def use_query(query: Callable, *args, **kwargs):
data, set_data = use_state(None)
loading, set_loading = use_state(True)
error, set_error = use_state(None)
@use_effect
async def load_data():
set_loading(True)
try:
# Will return an async callable if the value is already async.
# If the value is sync, then `database_sync_to_async` will be invoked
set_data(convert_to_async(query)(*args, **kwargs))
except Exception as error:
set_error(error)
finally:
set_loading(False)
return data, loading, error
data, loading, error = use_query(Model.objects.all, example_val, value=other_example) Perhaps we make the name even more generic, such as This interface can't cleanly be expanded to edit, update, and creation though... I think we should push this hotfix PR forward until Django's async ORM is released. |
We'd take an approach similar to Apollo's If this is truly blocking we can push forward, but ultimately I'd like to remove this functionality in favor of hooks. We should brainstorm the interface for these hooks in a separate issue. |
That useMutation API frankly looks quite ugly. That would be a really tough bullet for Django developers to swallow. |
Is it worth pushing out this PR just to enable Django ORM behavior to be similar to the other frameworks IDOM supports? If not, I'll close this PR. |
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.
I can see it taking a bit for us to hammer out the details of a hook-based alternative. We can do this as a short-term solution if you think that's necessary.
If we're going to have to back this out at some point, I think it might be more realistic to just document how to use I don't think we should merge unless we can agree it's beneficial to keep this in long-term. As mentioned, I personally think it might be beneficial for IDOM to allow this behavior, despite it not being a good programming pattern. If a component is...
... then I think we may as well allow this to happen, but simply document that it is most likely a bad idea. If you disagree then this PR can be closed. |