Run a Python file from html using Django

Writing here

In this article, I'm writing about "How to use Django to execute a Python file prepared on the server from a web page and output the data passed from html to a csv file".

Also, the writing environment is OS: macOS Catalina version 10.15.4 Python:3.7.6 Django:3.0.3 It has become.

About Django

In Previous article, I wrote about the flow from installing Django to displaying html, so please refer to that for the introduction of Django etc. Please refer.

Python file preparation

Creating a python file

First, prepare the Python file you want to run on Django's server. For the sake of explanation, prepare the following Python file this time.

write_data.py


# coding:utf-8
import os
import csv

#Record data from html to csv file
def write_csv(data):
    datas = [data]
    with open(os.getcwd()+'/myapp/application/'+'data.csv','a') as f:
        writer = csv.writer(f, lineterminator='\n')
        writer.writerow(datas)

This will write that data to data.csv by calling it by passing the data as an argument to write_csv (). Note that here it is assumed that the Python file will be placed in the `<app name> / application``` folder & the csv file will be output, so ```os.getcwd () +'/ myapp / application /' Although it is +'data.csv' `, please read this part appropriately according to the environment.

Placement of Python files

Place the prepared Python file on Django's server. If you put the Python file in the `` ` / application``` folder, the directory in the app will look like this:

<Project name>
- db.sqlite3
- manage.py
- <Project name>
  - __init__.py
  - asgi.py
  - settings.py
  - urls.py
  - wsgi.py
  - __pycashe__
    - (.Multiple pyc files)
- <app name>
  - __init__.py
  - admin.py
  - apps.py
  - models.py
  - tests.py
  - urls.py
  - views.py
  - migrations
    - __init__.py
  - application  #Created folder
    - write_data.py  #Prepared Python file
- templates
- static

Of course, you don't have to put it here, so you can place the file anywhere.

Allow Python files to be executed from html

After preparing and arranging the file, let's actually execute the Python file from html and create a csv file. Before that, I think that it is easier to work after understanding what the data flow is like, so I would like to write the data flow assumed this time. スクリーンショット 2020-05-30 19.04.32.png I made it with PowerPoint, sorry for the rough figure, There are many parts that are different from the program for simplification, but the data flow up to writing to the csv file is like this. I would be happy if the image could be conveyed somehow.

html(index.html) → Send data to call_write_data () in myapp / views.py → Execute the write_csv () method of application / write_data.py in call_write_data () → The passed data is written to the csv file.

Expressed in words, it looks like this. Based on this, we will edit each file so that we can actually execute the Python file from html from the next.

html: Send data to views.py using ajax

In order to pass the data to the call_write_data () method in views.py, I would like to send the data using ajax on html. I think there are various methods for this, so please use the method that suits your application.

index.html


{% load static %}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>HTML</title>
    <link rel='stylesheet' type='text/css' href="{% static 'style.css' %}"/>
    <script type="text/javascript" src="{% static 'script.js' %}"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  </head>
    
  <body>
      <span>Please press the button after entering the characters</span>
      <br>
      <input type="text" size="50" id="input_form">
      <button type="button" onclick="clickBtn()">Send</button>
      
      <script>
        function clickBtn() {
          var txt = document.getElementById("input_form").value;
          
          $.ajax({
            url: "{% url 'myapp:call_write_data' %}",
            method: 'GET',
            data: {"input_data": txt},
            dataType: "text",
            contentType: "application/json",
            beforeSend: function(xhr, settings) {
              if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                xhr.setRequestHeader("X-CSRFToken", csrf_token);
              }
            },
            error: function(xhr, status, error) {
              console.log("error")
            }
          })
          .done(function(data) {
            console.log("Success"); 
          });
          
          // csrf_Used to get token
          function getCookie(name) {
            var cookieValue = null;
            if (document.cookie && document.cookie !== '') {
              var cookies = document.cookie.split(';');
              for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) === (name + '=')) {
                  cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                  break;
                }
              }
            }
            return cookieValue;
          }

          //Csrf in header_Function that grants token
          function csrfSafeMethod(method) {
            // these HTTP methods do not require CSRF protection
            return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
          };
        }
        
      </script>
  </body>
</html>

When you press the send button, clickBtn () is executed and the data is sent by ajax. The url part is myapp: call_write_data, which sends the data to the method called call_write_data () described in views.py.

The data part is data: {" input_data ": txt}` ``, and the data receiving side can get the target data by specifying "input_data". There is only one here, but you can freely set the data format such as the number and type of data like data: {" data1 ": txt1," data2 ": txt2}` ``. ..

myapp / views.py: Specify the Python file and method you want to execute and execute

myapp/views.py


from django.shortcuts import render
from django.http import HttpResponse
# application/write_data.Import py
from .application import write_data

# Create your views here.
def index(req):
    return render(req, 'index.html')

#Method specified by url with ajax
def call_write_data(req):
    if req.method == 'GET':
        # write_data.py write_csv()Call the method.
        #Of the data sent by ajax"input_data"To get by specifying.
        write_data.write_csv(req.GET.get("input_data"))
        return HttpResponse()

Here, we get the data sent by ajax, pass it to the method of the Python file we want to execute, and call it.

myapp / urls.py: Allows html to send data to call_write_data () in views.py

myapp/urls.py


from django.urls import path
from . import views

app_name = 'myapp'
urlpatterns = [
    path(r'', views.index, name='index'),
    #Add the following(views.py call_write_data()Allows you to send data to)
    path("ajax/", views.call_write_data, name="call_write_data"),
]

By passing the path, you can send data from html to the specified method of views.py using ajax communication.

Check if it is actually written to the csv file

This completes the necessary editing.

$ python manage.py runserver

Start the server with, access the displayed address (display html), enter appropriate characters in the input form, and then press the send button.

- <app name>
  - __init__.py
  ...
  - application
    - write_data.py
    - data.csv  #Generated csv file

In this way, the csv file is generated in the application folder created in the application, and if the input character string is recorded in the file, the data is sent without any problem & the Python file is executed.

Supplement

This time I explained how to execute a Python file from html and write the sent data to a csv file, but vice versa.

For the sake of simplicity, I would like to do "get the data passed from write_data.py in views.py and pass it to html for display". Only the files with changes are listed below.

myapp/application/write_data.py Add a method called return_text ().

myapp/application/write_data.py


   # coding:utf-8

   import os
   import csv

   #Record data from html to csv file
   def write_csv(data):
       datas = [data]
       with open(os.getcwd()+'/myapp/application/'+'data.csv','a') as f:
           writer = csv.writer(f, lineterminator='\n')
           writer.writerow(datas)

   #Add the following(return_text()When you call"Hello!!"Is returned)        
+  def return_text():
+      return "Hello!!"

myapp/views.py Call return_text () added in write_data.py and get the returned character string (store it in data). Pass that data to html using `HttpResponse ()`.

myapp/views.py


  from django.shortcuts import render
  from django.http import HttpResponse
  # application/write_data.Import py
  from .application import write_data

  # Create your views here.
  def index(req):
      return render(req, 'index.html')

  #Method specified by url with ajax
  def call_write_data(req):
      if req.method == 'GET':
          # write_data.py write_Call the csv method.
          #Of the data sent by ajax"input_data"To get by specifying.
          write_data.write_csv(req.GET.get("input_data"))
        
          # write_data.Newly written method in py(return_text())To call.
+         data = write_data.return_text()
          #Pass the received data to html.
+         return HttpResponse(data)

index.html When ajax communication is successful, the argument passed by HttpResponse () is passed to the `` `.done (function (data) {``` part, so that data is displayed on the page.

index.html


  {% load static %}
  <!DOCTYPE html>
  <html>
    <head>
      <meta charset="utf-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <title>HTML</title>
      <link rel='stylesheet' type='text/css' href="{% static 'style.css' %}"/>
      <script type="text/javascript" src="{% static 'script.js' %}"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    </head>
    
    <body>
      <span>Please press the button after entering the characters</span>
      <br>
      <input type="text" size="50" id="input_form">
      <button type="button" onclick="clickBtn()">Send</button>
      
      <!-- views.Display the string passed from py.-->
+     <br>
+     <span id="text"></span>
      
      <script>
        function clickBtn() {
          var txt = document.getElementById("input_form").value;
          
          $.ajax({
            url: "{% url 'myapp:call_write_data' %}",
            method: 'GET',
            data: {"input_data": txt},
            dataType: "text",
            contentType: "application/json",
            beforeSend: function(xhr, settings) {
              if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                xhr.setRequestHeader("X-CSRFToken", csrf_token);
              }
            },
            error: function(xhr, status, error) {
              console.log("error")
            }
          })
          .done(function(data) {
            // views.py call_write_data()HttpResponse returned in(data)Data can be obtained here.
            //Rewrite the contents of the span part added at the bottom of the form.
+           document.getElementById("text").textContent = data;
            console.log("Success"); 
          });
          
          // csrf_Used to get token
          function getCookie(name) {
            var cookieValue = null;
            if (document.cookie && document.cookie !== '') {
              var cookies = document.cookie.split(';');
              for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) === (name + '=')) {
                  cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                  break;
                }
              }
            }
            return cookieValue;
          }

          //Csrf in header_Function that grants token
          function csrfSafeMethod(method) {
            // these HTTP methods do not require CSRF protection
            return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
          };
        }
        
      </script>
    </body>
  </html>

This will pass the string "Hello !!" to the html when the submit button is pressed and the Python file is executed correctly, and the string "Hello !!" passed to the bottom of the input form will be displayed. think.

By applying this, it is possible to execute the Python file on the server, read and write the data of the file on the server, and reflect the data on html.

Recommended Posts

Run a Python file from html using Django
Run a python script from excel (using xlwings)
Run Ansible from Python using API
Create a deb file from a python package
Use Django from a local Python script
Run a Python script from a C # GUI application
Create a GIF file using Pillow in Python
Create a tool to automatically furigana with html using Mecab from Python3
Run python from excel
Create wav file from GLSL shader using python3
I tried reading a CSV file using Python
Create a MIDI file in Python using pretty_midi
Read line by line from a file with Python
Make a copy of a Google Drive file from Python
(Python) Try to develop a web application using Django
[CRUD] [Django] Create a CRUD site using the Python framework Django ~ 1 ~
I tried running python etc. from a bat file
A memorandum to run a python script in a bat file
DJango Note: From the beginning (using a generic view)
Steps from installing Python 3 to creating a Django app
Build a Python virtual environment using venv (Django + MySQL ①)
I tried reading data from a file using Node.js.
Python script to create a JSON file from a CSV file
Run a Python file with relative import in PyCharm
[CRUD] [Django] Create a CRUD site using the Python framework Django ~ 3 ~
[CRUD] [Django] Create a CRUD site using the Python framework Django ~ 4 ~
[CRUD] [Django] Create a CRUD site using the Python framework Django ~ 5 ~
A little bit from Python using the Jenkins API
[Python] Start a batch file from Python and pass variables.
How to run a Python file at a Windows 10 command prompt
How to run a Python program from within a shell script
Python> Read from a multi-line string instead of a file> io.StringIO ()
Shoot time-lapse from a PC camera using Python and OpenCV
Execute Python script from batch file
Call a Python function from p5.js.
Python: Exclude tags from html data
Touch a Python object from Elixir
I made a Line-bot using Python!
Using Rstan from Python with PypeR
Create a python GUI using tkinter
Django: Import a class from a string
Drawing a silverstone curve using python
Create a binary file in Python
python / Make a dict from a list.
Using Cloud Storage from Python3 (Introduction)
Run Aprili from Python with Orange
Python error detection run from Powershell
Extract the targz file using python
Run Python scripts synchronously from C #
Install Python framework django using pip
Run a simple algorithm in Python
Precautions when using phantomjs from python
Access spreadsheets using OAuth 2.0 from Python
[Python] File operation using if statement
Run Python Scripts from Cisco Memorandum_EEM
Create a file uploader with Django
Try using Amazon DynamoDB from Python
Process Splunk execution results using Python and save to a file
Read a file in Python with a relative path from the program
Call dlm from python to run a time-varying coefficient regression model
[Python] Read a csv file with a large data size using a generator