【问题标题】:How to disable form fields and buttons until a Python subprocess has terminated?如何在 Python 子进程终止之前禁用表单字段和按钮?
【发布时间】:2012-11-04 16:37:29
【问题描述】:

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

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

  1. 第一次加载 HTML 页面时,启用所有表单 stop subprocess 按钮除外的字段和按钮(因为 还没有什么可以停止的)
  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

非常感谢您!

【问题讨论】:

  • 您是在寻找有关如何使用 jquery 禁用表单元素的信息,还是需要有关整体想法的帮助?
  • @noisewaterphd:我知道一般如何使用 jQuery 禁用表单元素。我的问题是如何让 jQuery 知道我的子进程的状态。

标签: javascript jquery python django subprocess


【解决方案1】:

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

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

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

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

【讨论】:

  • 是的,你知道。 :) 你的建议听起来很合理。你能给我一些关于如何使用 Ajax 请求触发 Python 子进程的通用伪代码吗?
  • Ajax 请求可以像任何其他请求一样被处理,您只需要后端的视图来响应它。
  • 这将阻塞服务器线程,直到该进程完成,不是吗?你需要一个异步服务器来避免阻塞。
【解决方案2】:

首先,你可以像这样设置 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 响应成功 = True,这将反过来触发成功函数。

from django.utils import simplejson as json

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

edit:这个我还没有测试过,你还得在AJAX请求中填写详细信息,但我认为它可能会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-27
    • 2016-06-15
    • 2015-06-20
    • 1970-01-01
    • 2012-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多