0

我是 JavaScript/jQuery 新手,需要一些帮助。在 Django 应用程序中,我有一个包含两个表单的 HTML 页面。当单击第一个表单的提交按钮时,相应的 Django 视图会启动一个 Python 子进程。第一种形式的字段用于将参数传递给该子流程。第二种形式不包含任何字段。它的唯一目的是在单击其提交按钮时停止相同的子进程。

整个表单提交过程发生在服务器端。我想知道如何使用 jQuery 完成以下行为:

  1. 首次加载 HTML 页面时,启用除停止子流程按钮之外的所有表单字段和按钮(因为还没有什么可停止的)
  2. 单击启动子流程按钮时,应禁用表单的字段和按钮本身,直到子流程完成。同时,应该启用停止子进程按钮。
  3. 单击停止子进程按钮时,再次禁用它,直到子进程真正完成。子流程完成后,返回步骤 1。

我一般都知道如何使用 jQuery 来禁用表单元素。我的问题是如何让 jQuery 知道我的子进程的状态。

以下是 Django 视图的相关代码:

def process_main_page_forms(request):
    if request.method == 'POST':
        if request.POST['form-type'] == u'webpage-crawler-form':
            template_context = _crawl_webpage(request)

        elif request.POST['form-type'] == u'stop-crawler-form':
            template_context = _stop_crawler(request)
    else:
        template_context = {
            'webpage_crawler_form': WebPageCrawlerForm(),
            'stop_crawler_form': StopCrawlerForm()}

    return render(request, 'main.html', template_context)

def _crawl_webpage(request):
    webpage_crawler_form = WebPageCrawlerForm(request.POST)

    if webpage_crawler_form.is_valid():
        url_to_crawl = webpage_crawler_form.cleaned_data['url_to_crawl']
        maximum_pages_to_crawl = webpage_crawler_form.cleaned_data['maximum_pages_to_crawl']

        program = 'python manage.py crawlwebpages' + ' -n ' + str(maximum_pages_to_crawl) + ' ' + url_to_crawl
        p = subprocess.Popen(program.split())

    template_context = {
        'webpage_crawler_form': webpage_crawler_form,
        'stop_crawler_form': StopCrawlerForm()}

    return template_context

def _stop_crawler(request):
    stop_crawler_form = StopCrawlerForm(request.POST)

    if stop_crawler_form.is_valid():
        with open('scrapy_crawler_process.pid', 'rb') as pidfile:
            process_id = int(pidfile.read().strip())

        # These are the essential lines
        os.kill(process_id, signal.SIGTERM)
        while True:
            try:
                time.sleep(10)
                os.kill(process_id, 0)
            except OSError:
                break
        print 'Crawler process terminated!'

    template_context = {
        'webpage_crawler_form': WebPageCrawlerForm(),
        'stop_crawler_form': stop_crawler_form}

    return template_context

非常感谢您!

4

2 回答 2

0

我会考虑将子进程作为对 django 视图的 Ajax 请求触发,当您触发 Ajax 请求时,还调用您的 JS 方法来禁用所有元素。

当视图完成处理时,它将返回一个对进行 Ajax 调用的 Javascript 的响应。当 javascript 收到此响应时,重新启用所有表单元素。

这将允许您还通过来自 Django 的 Ajax 响应向客户端发送有关处理结果的错误/消息。

我希望我已经正确地理解了你的情况。

于 2012-11-16T00:11:46.377 回答
0

首先,您可以像这样设置 jQuery

$(document).ready(function() {
  $('#startButton').bind('click', startProcess());
});

var startProcess() = function {
  $('#startButton').unbind('click');
  .ajax({
    url: '',
    data: {},
    dataType: '',
    type: '',
    beforeSend: function() {
      $('#stopButton').bind('click', stopProcess());
    },
    success: function(data) {
      $('#stopButton').unbind('click');             
    },
    error: function(data) {
      // Handle error
    },
    complete: function(data) {
      $('#startButton').bind('click', startProcess());
    },
};

var stopProcess() = function {
  $('#stopButton').unbind('click');

  // Use AJAX to tell django to stop processing

  $('#startButton').bind('click', startProcess());
};

您可以让 Django 以 success = True 响应,这反过来会触发成功函数。

from django.utils import simplejson as json

def json_response(message):
    return HttpResponse(json.dumps(dict(success=True, message=message)))

编辑:我还没有对此进行测试,您还必须在 AJAX 请求中填写详细信息,但我认为它可能会有所帮助。

于 2012-11-19T17:08:58.460 回答