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
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]
.
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 %}
<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.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
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/
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:)
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:
<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:
url(r'^submit', views.submit)
and your views.py would have the function that would get the parameters that were passed through the post:
def submit(request):
info=request.POST['info']
# do something with info
This link gives a more in depth explanation.
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.