I am a bit confused on how to proceed with my program. I have a django view that asks the user to input a first name and lastname, then this go to a celery task which process the data and save it to the database. Now, while the task is processing, I want an animated gif to display so the user will know that something is happening.(I've read somewhere here in SO that animated gif is better) then if the task is done, it will redirect to a page that tells the user the process is complete. I have done my research and found out that I should get the task_id
and send it to an ajax request.
My problem is how to use ajax. How can I get the task_id from ajax? Or pass the task_id to the ajax request.
EDIT: ** I know this is INCOMPLETE. VERY INCOMPLETE**
Here is some of my codes. It does not do much because I still have to grasp the concept of using ajax. But what I want is when I submit the form, the spinner gif will appear and at the same time, celery will process my tasks. When celery is done processing the task, it will redirect to a page where it says "Success" or anything.
views.py:
def addUser(request):
if request.method == 'POST':
addUser = userform(request.POST)
if addUser.is_valid():
task = create_user.apply_async((addUser.cleaned_data,), countdown=20)
return render_to_response('loading.html', {'task_id': task.task_id})
else:
addUser = userform()
return render(request, 'addUser.html', {'addUser':addUser})
addUser.html
<form method="POST">
{% csrf_token %}
{{ addUser }}
<input type="submit" value="Submit">
</form>
loading.html
<html>
<script>
<head>
<script src="{{ STATIC_URL }}js/jquery-ui.min.js"></script>
<script type="text/javascript">
var formData = task_id; // task id of my celery task
$.ajax({
url : "templates/success.html", //from what I know, this URL is where the AJAX will go after processing
type: "POST",
data : formData,
success: function(data, textStatus, jqXHR)
{
alert("Success")
},
error: function (jqXHR, textStatus, errorThrown)
{
alert("Failed")
}
});
</script>
</head>
<body><center>
{% load static %}
<img src="{% static 'images/ripple.gif' %}" alt="Hi!" height="150" width="150" />
</center>
</body>
</html>
tasks.py
@task(ignore_result=True)
def create_user(data):
user = UserInfo(fname=data['fname'], lname=data['lname'])
user.save()
return None
I am not sure where AJAX will go, if it's in the form(addUser.html)
or in the loading.html
Please do correct me if I'm wrong. Thank you for the help!
The idea is to launch the long running task, when you execute one it returns an AsyncResult object you have to get the "task_id" and return it to the client. The client side (javascript) would make a GET request for example to /check_status/ and pass the "task_id" to the server. The server will ask celery using that task_id and return to the client if the task finished or not.
def view_with_task(request):
#your code
# send the task to the worker and get the task_id
async_result = your_task.delay()
#code
ctx = {}
ctx['task_id'] = async_result.task_id
return render(tpl, ctx)
from celery import AsyncResult
def check_status(request):
task_id = request.GET.get('task_id')
if task_id:
async_result = AsyncResult(task_id)
return Jsonresponse({'finish': async_result.ready()})
return JsonResponse({'finish': False})
BTW, there is a project to do this without pain neither too much code. Thanks
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With