django / channels

Developer-friendly asynchrony for Django
https://channels.readthedocs.io
BSD 3-Clause "New" or "Revised" License
6.02k stars 793 forks source link

Slicing does not work when using the @database_sync_to_async decorator #2003

Closed tanrax closed 1 year ago

tanrax commented 1 year ago

When I try to get a list of results, using ORM, and try to do a slicing it doesn't work. On the other hand, if I transform to list or tuple it works.

For example, the following code:

@database_sync_to_async
def get_all_cats():
    return Cat.objects.all().order_by("-id")[:3]

Output: SynchronousOnlyOperation at /cats/ You cannot call this from an async context - use a thread or sync_to_async.

But...

@database_sync_to_async
def get_all_cats():
    return tuple(Cat.objects.all().order_by("-id")[:3])

It works well.

And, of course, work.

@database_sync_to_async
def get_all_cats():
    return Cat.objects.all().order_by("-id")

Thanks in advance for the great work of Channels.

carltongibson commented 1 year ago

As per the Limiting QuerySets docs, slicing the QuerySet in general returns a new QuerySet rather than forcing it to evaluate. The tuple call does that.