从AJAX请求调用Django视图(解析celery task_id)

时间:2018-08-01 11:50:15

标签: javascript ajax django celery django-urls

我正在尝试将芹菜任务中的数据输出到单独的窗口中。我是l2->current->nextprintf的新手,这是我当前的问题所在。执行视图后,启动celery任务并呈现下一个html页面(JavaScript):

success.html

AJAX

我知道调用success.html是因为至少打开了一个窗口。这是{% block content %} <body> {% if task_id %} <h1>task_id has been called: {{ task_id }}</h1> <script src="{% static 'MyAPP/bootstrap/js/task_output_retrieval.js' %}"></script> <script type='text/javascript'> task_state("{{ task_id }}"); </script> <script src="{% static 'MyAPP/bootstrap/js/update-hello-user.js' %}"></script> <script type='text/javascript'> second(); </script> <h1> END </h1> {% endif %} </body> {% endblock content %}

task_output_retrieval.js

JavaScript

url.py

.js

视图:

admin_scripts.py

function task_state (task_id) {
    var taskID = task_id; 
    var newWin = window.open('', 'new window', 'width=200, height=100');

    $.ajax({
            url: '{% url validate_task_state %}', 
            data: {'taskID':taskID},
            method: 'POST',
            dataType : "json",
            success: function(data){
                $(newWin.document.body).html(data);
                newWin.document.write(data);
                newWin.document.close();
                newWin.focus();
                newWin.print();
                newWin.close();
            },
            error: function (){ alert('An error occured'); }
    });
}

task_state(task_id);

我不完全了解url(r'^ajax/task_state/$', task_state, name='validate_task_state'), # for ajax 中仍有许多未解决的问题,通过反复试验我会到达那里,但是目前def task_state(request): print ("You reached the task_state function") data = 'Fail' task_id = request.GET.get('task_id') #task_id = request.session['task_id'] try: async_result = AsyncResult(task_id) except KeyError: ret = {'error':'No optimisation (or you may have disabled cookies).'} return HttpResponse(json.dumps(ret)) print ("request.is_ajax(): {0}".format(request.is_ajax())) if request.is_ajax(): if 'task_id' in request.POST.keys() and request.POST['task_id']: task_id = request.POST['task_id'] async_result.get() data = { 'state': async_result.state, 'result': async_result.result, } #data = async_result.result or async_result.state print ("data: {0}".format(data)) else: data = 'No task_id in the request' else: raise SuspiciousOperation("This is not an ajax request.") json_data = json.dumps(data) return HttpResponse(json_data, content_type='application/json') 没有被调用。我怀疑问题出在AJAX调用(“ URL”)上,但我不知道为什么。我要去哪里错了?

更新:选中“ JS测试材料”复选框后,将呈现task_state,没有错误。从task_state内部调用了AJAX JavaScript(success.html),这得到了验证,因为我从task_output_retrieval.js调用了2个JavaScript文件(另一个是success.html)。 success.html的窗口被打开,并且update-hello-user.js的弹出窗口也被显示。它在task_output_retrieval.js中,在其中调用视图:

task_output_retrieval.js

但这不会呈现。

这是控制台的输出:

update-hello-user.js

1 个答案:

答案 0 :(得分:2)

让我着眼于您的代码的问题是您在JavaScript文件中使用{% url validate_task_state %}。如果您遵循推荐的最常用方法来设置Django并提供其静态内容,则模板引擎将不会处理您的JavaScript文件,并且不会处理该模板标记。另外,它的引号周围需要加引号,因此{% 'url validate_task_state' %}

您应该更改success.html模板,以将所需的URL传递给task_state函数,如下所示:

<script src="{% static 'MyAPP/bootstrap/js/task_output_retrieval.js' %}"></script>
<script type='text/javascript'> task_state("{% url 'validate_task_state' %}", "{{ task_id }}"); </script>

并修改函数以采用新参数:

function task_state (query_url, task_id) {
    var taskID = task_id; 
    var newWin = window.open('', 'new window', 'width=200, height=100');

    $.ajax({
            url: query_url, 
            data: {'taskID':taskID},
            method: 'POST',
            dataType : "json",
            success: function(data){
                $(newWin.document.body).html(data);
                newWin.document.write(data);
                newWin.document.close();
                newWin.focus();
                newWin.print();
                newWin.close();
            },
            error: function (){ alert('An error occured'); }
    });
}

您在评论中说Django没有看到请求。常见问题是CSRF保护:自定义POST请求需要传递CSRF令牌,否则将被拒绝。具体操作方法部分取决于您的特定配置,但总的来说,我会这样做:

// Grab the CSRF token from the cookie.
var csrftoken = $.cookie('csrftoken');
$.ajax({
  type: "POST",
  url: "... my url ...",
  headers: {
    // Pass the token with the query.
    'X-CSRFToken': csrftoken
  },
  // other ajax options...
});