从提交在 Django 中运行 python 脚本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29977495/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 05:14:48  来源:igfitidea点击:

Running python script in Django from submit

pythondjango

提问by Matt

Perhaps there is a different way of going about this problem, but I am fairly new to using Django.

也许有一种不同的方式来解决这个问题,但我对使用 Django 还很陌生。

I have written a custom python script and would like to run a function or .py file when a user presses a "submit" button on the webpage.

我编写了一个自定义 python 脚本,并希望在用户按下网页上的“提交”按钮时运行函数或 .py 文件。

How can I get a parameter to be passed into a python function from a submit button using Django?

如何使用Django从提交按钮获取要传递给python函数的参数?

回答by neatnick

Typically what is done is you'd have your form submit a post request. You'd then intercept the request in your urls.py, where you'd call your function. So if your form looks like this:

通常所做的是让您的表单提交发布请求。然后您将在您的 urls.py 中拦截请求,您将在其中调用您的函数。因此,如果您的表单如下所示:

<form action="submit" method="post">
    <input type="text" name="info"><br>
    <input type="submit" value="Submit">
</form>

your urls.py would have something like this:

你的 urls.py 应该是这样的:

url(r'^submit', views.submit)

and your views.py would have the function that would get the parameters that were passed through the post:

并且您的 views.py 将具有获取通过帖子传递的参数的函数:

def submit(request):
    info=request.POST['info']
    # do something with info

This linkgives a more in depth explanation.

这个链接给出了更深入的解释。

回答by kossta

After googling for a couple of days, i managed to piece together some solution on this question, which i needed for my project.

在谷歌搜索了几天之后,我设法拼凑了一些关于这个问题的解决方案,这是我的项目所需要的。

SwankSwashbucklers gave the general approach and i just wanted to add to it to complete the circle. This might not be the only solution so i am just giving one working example. So.. your template should contain the following code (as above with some extras):

SwankSwashbucklers 给出了一般方法,我只是想添加它以完成圆圈。这可能不是唯一的解决方案,所以我只是举一个有效的例子。所以..你的模板应该包含以下代码(如上,还有一些额外的):

your_template.html

your_template.html

{% extends base.html %}
{% block main_content %}
<form action="your_view_url" method="post">{% csrf_token %}
  {{ form.as_table }}
  // <input type="text" name="info_name" value="info_value">
  <input type="submit" value="Submit">
</form>
<p> Post Data: {{ info }} </p>
<p> Result: {{ output }} </p>
{% endblock main_content %}

If you defined your form in forms.pyand/or using your models for form rendering, then examine the rendered HTML to find out what was given to the "value" attributes rendered by Django in the form. "value" is what will be submitted in your POST request.

如果你在forms.py 中定义了你的表单和/或使用你的模型来呈现表单,那么检查呈现的 HTML 以找出给表单中由 Django 呈现的“值”属性的内容。“值”是将在您的 POST 请求中提交的内容。

Your defined view will display the form, and also will process it once submited, so you will have 2 sections in it with an 'if' statement. Django uses "GET" to open views, so the initial rendering display blank form

您定义的视图将显示表单,并在提交后对其进行处理,因此您将在其中包含 2 个带有“if”语句的部分。Django使用“GET”打开视图,所以初始渲染显示空白表单

views.py

视图.py

import subprocess

def your_view_name(request):
  if request.method == 'GET':
    form = your_form_name() 
  else:
    if form.is_valid():
      info = request.POST['info_name']
      output = script_function(info) 
      // Here you are calling script_function, 
      // passing the POST data for 'info' to it;
      return render(request, 'your_app/your_template.html', {
        'info': info,
        'output': output,
      })
  return render(request, 'your_app/your_template.html', {
    'form': form,
  })

def script_function( post_from_form )
  print post_from_form //optional,check what the function received from the submit;
  return subprocess.check_call(['/path/to/your/script.py', post_from_form])  

forms.py

表格.py

class your_form_name(forms.Form):
  error_css_class = 'error' //custom css for form errors - ".error";
  required_css_class = 'required' //custom css for required fields - ".required";
  info_text = forms.CharField()

The "info_text" is what will be rendered in the template as in "input" field when you call form = your_form_name(). More on Django forms is here https://docs.djangoproject.com/en/1.9/ref/forms/fields/

当您调用form = your_form_name()时,“info_text”将在模板中呈现为“输入”字段中的内容。更多关于 Django 表单的信息在这里https://docs.djangoproject.com/en/1.9/ref/forms/fields/

When you press submit, the form will submit the data back to itself, so your view will pick that its a POST and will run is_valid, and then the value of outputwill be the error code returned by subprocess.check_call. If your script run OK, the value of "output" will be "0".

当您按下提交,表单将数据提交回自己,所以你的观点会选择它的一个POST和运行is_valid,然后值输出将被返回的错误代码subprocess.check_call。如果您的脚本运行正常,“输出”的值将为“0”。

This is for "Django 1.4", and "Python 2.6". Latest versions have subprocess.check_outputwhich can actually return the output from the script so you can render it back on the template.

这适用于“Django 1.4”和“Python 2.6”。最新版本有subprocess.check_output,它实际上可以从脚本返回输出,以便您可以将其呈现回模板。

Hope this helps:)

希望这可以帮助:)

回答by alxs

What @SwankSwashbucklers says is the way to go.

@SwankSwashbucklers 所说的是要走的路。

If you also want to maintain your script separate from the view, you can also use a custom management commandand use call_commandto call it in the view. This way you can run the script from the command line as well with manage.py mycommand [myargument].

如果您还想将您的脚本与视图分开维护,您还可以使用自定义管理命令并使用call_command在视图中调用它。通过这种方式,您也可以从命令行运行脚本manage.py mycommand [myargument]

回答by dain

In django 1.11 and python 3.6, I had to use

在 django 1.11 和 python 3.6 中,我不得不使用

return subprocess.run(['python', 'path_to_script//prog17.py', post_from_form], shell=False, timeout=1800)

The rest of @kossta's code worked fine.

@kossta 的其余代码运行良好。