Django - How to use asynchronous task queue with c

2020-06-28 08:45发布

问题:

#In my views.py file
pi1 = None
pis1 = None
def my_func():
    #Essentially this function sets a random integer to pi1 and pis1
    global pi1, pis1
    pi1 = randint(0,9)
    pis1 = randint(0,9)
    return        

def index(request):

    my_func()

    context = {
        "pi1" : pi1,
        "pis1" : pis1,
    }

    return render(request, "index.html", context)

#In the index.html file
<h1>{{ pi1 }}</h1>
<h1>{{ pis1 }}</h1>

I've removed a lot of my code for simplicity, but this is the gist of it. Despite the code that I've posted for my_func, it is a time consuming function that causes index.html to load for awhile when it is accessed. How would I run my_func in the backround using celery and redis so that index.html loads more quickly?

I've read the celery documentation, but I am still having trouble setting up celery and redis. Thank you.

回答1:

As is said previous, you might not need celery. Here's an example derived from case 2 of this: https://zapier.com/blog/async-celery-example-why-and-how/. It's fully working for me:

from time import sleep
import json
from django.http import HttpResponse
from django.shortcuts import render

def main_view(request):
    return render(request, 'index.html')

def ajax_view(request):
    sleep(10) #This is whatever work you need
    pi1 = "This is pi1" #I just made pi1/pis1 random values
    pis1 = "This is pis1"
    context = {
        "pi1" : pi1,
        "pis1" : pis1,
    }
    data = json.dumps(context)

    return HttpResponse(data, content_type='application/json')

My index.html contains:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Main View</title>
    <script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
    <script>
    $(document).ready(function(){
        $.ajax({
            url: "/test_ajax/",
        }).done(function( data) {
            $("#pi1").text(data.pi1);
            $("#pis1").text(data.pis1); 
        });
    });
</script>
  </head>
  <body>
      <h1 id = "pi1">Loading</h1>
      <h1 id = "pis1">Loading</h1>
  </body>
</html>

And my urls.py contains:

from django.conf.urls import include, url
from django.contrib import admin
from testDjango.test import main_view, ajax_view

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^test/', main_view),
    url(r'^test_ajax/', ajax_view)
]

What happens when I visit localhost:8000/test/ is that I instantly see:

After about 10 seconds, I then see:

The idea is that you return your page instantly and use jquery to fetch the result of the operation whenever that's finished and update your page accordingly. You can add more things like progress bars/loading image etc. For your example, you can do the processing for pi1 and pis in the background and load it into the HTML after that's finished.



回答2:

You don't need celery here. You can load these values on page with AJAX request. You should create a separate view that will calculate this values and after the index.html is loaded call it with javascript.