Skip to content Skip to sidebar Skip to footer

Running Python Script In Django From Submit

Perhaps there is a different way of going about this problem, but I am fairly new to using Django. I have written a custom Python script and would like to run a function or .py fil

Solution 1:

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:

<formaction="submit"method="post"><inputtype="text"name="info"><br><inputtype="submit"value="Submit"></form>

your urls.py would have something like this:

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

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

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

This link gives a more in depth explanation.

Solution 2:

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):

your_template.html

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

If you defined your form in forms.py and/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.

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

views.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

classyour_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/

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 output will be the error code returned by subprocess.check_call . If your script run OK, the value of "output" will be "0".

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

Hope this helps:)

Solution 3:

In django 1.11 and python 3.6, I had to use

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

The rest of @kossta's code worked fine.

Solution 4:

What @SwankSwashbucklers says is the way to go.

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

Solution 5:

Except for the last part(calling the python script), @kosstas's code ran perfectly in my system. I am sharing what I had different. I am using Python 3.8 and Django 3.1. I had to use -

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

This code did not display the output in my system. To see the output, I had to put "stdout=PIPE" in place of "timeout=1800". That is:

output = run([sys.executable,'windows_path_like_D:\\path_to_script\\prog17.py', model_name], shell=False, stdout=PIPE)

For this at the top, I had to include:

from subprocess import run, PIPE

This was a great relief to me to see the output in my own eyes instantly!

Post a Comment for "Running Python Script In Django From Submit"