Skip to content
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

Call Django Class based view function with Django-Q's async_task #463

Closed
ghost opened this issue Aug 3, 2020 · 6 comments
Closed

Call Django Class based view function with Django-Q's async_task #463

ghost opened this issue Aug 3, 2020 · 6 comments

Comments

@ghost
Copy link

ghost commented Aug 3, 2020

I can't call async_task on a Django class based view function. Considering following case, where I have a DRF view:

class Greeter(generics.GenericAPIView)

    def greet(self, name):
        print("Hello: ")
        sleep(5)
        print(name)

    def post(self, request, *args, **kwargs):
        # enqueue the task
        async_task(self.greet, "world")

        return Response(
            {"message": "you should see this right away"}, status=status.HTTP_200_OK
        )

When trying to call async_task on a Django class based view function, following errors occur:

  • async_task(self.greet) returns an cannot pickle '_io.BufferedReader' object error
  • async_task("self.greet") returns an No module named 'self' error

I have no issues when putting the greet function outside de class.

edit: correcting function names

@Koed00
Copy link
Owner

Koed00 commented Aug 3, 2020 via email

@ghost
Copy link
Author

ghost commented Aug 3, 2020

As a quick fix you could try to async the import path i.e. "Greeter.greet"

I tried that as well, but then I have a No module named Greeter error.

@Koed00
Copy link
Owner

Koed00 commented Aug 7, 2020

That probably means you are not giving it the full import parth ie: "myapp.Greeter.greet"

@mosi-kha
Copy link

mosi-kha commented Aug 12, 2020

hi
how in case that we need to create an instance of an object then pass that function from the instance, set that function to async_task?
ex: async_task(Test().print_test) but raise some pickle error

@Koed00
Copy link
Owner

Koed00 commented Aug 12, 2020 via email

@ghost ghost closed this as completed Aug 13, 2020
@rafael-h-ferreira
Copy link

I too have a class with many static methods and I wish to call the class functions. Instead of creating one separate task for each class function, I created one task that will run the class functions:

from my_proj import ProjClass
def run_task(class_static_method: str, *args, **kwargs):
    func = getattr(ProjClass, class_static_method)
    return func(*args, **kwargs)

Then you may call it like:

async_task("my_proj.run_task", "class_static_function", arg1)

Of course, if you need a class instance you need to instantiate it first in the run_task. If you also need to pass class args, you probably need a dict arg for the class args and other for the function args.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants