Flask (https://flask.palletsprojects.com/en/2.0.x/) — один из известных веб-фреймворков Python. Он известен фреймворком Micro. Микрофреймворк не означает, что он имеет только один файл для хранения кодов или имеет несколько функций. Micro означает, что у него простое ядро, но оно расширяемо, поэтому мы можем освободить те расширения, которые хотели бы использовать [1]. У Flask есть много расширений, которые мы можем использовать, некоторые популярные расширения Flask, такие как Flask-SQLAlchemy, которые используют расширение SQLAlchemy, набор инструментов Python SQL и Object Relational Mapper (ORM), чтобы помочь разработчикам приложений с гибкостью SQL [2] .

Чтобы изучить Flask, вы должны сначала знать Python, лучше на среднем уровне. Хотя явно не указано, что использование модели-представления-контроллера (MVC), как в некоторых веб-фреймворках, для разделения между моделью, структурой данных и модулем базы данных, модулем шаблона и контроллерами в качестве логического модуля, мы можем разделить модули, аналогичные MVC в Flask. В шаблонах Flask использует Jinja (https://jinja.palletsprojects.com/en/3.0.x/). В моделях мы можем создавать свои собственные файлы моделей для работы со структурой данных и контроллер для работы с логикой, но здесь модель и контроллер — это один файл, это route.py.

В этой статье речь пойдет о создании простого приложения Create-Read-Update-Delete или CRUD с использованием Flask, поэтому мы изучим Flask, используя его для создания CRUD.

I.Requirements
Чтобы создать приложение CRUD с использованием Flask, нам понадобятся следующие инструменты:

  • Python (www.python.org). На вашем компьютере должен быть установлен Python. Лучше установить Python 3.x, текущая версия на момент написания этой статьи — Python 3.10.0.
  • Фляга (https://flask.palletsprojects.com). На вашем компьютере должен быть установлен Flask. Мы поговорим об этом подробно позже.
  • IDE (интегрированная среда разработки) или текстовый редактор. Spyder (www.spyder-ide.org) — одна из хороших IDE для использования, и я недавно использовал ее помимо Jupyter-Notebook в качестве редактора кода Python (https://wansofwan.medium.com/spyder-a-good-ide -для-питона-выбрать-4f03cde74fbc)

II.Инструменты

Я предполагаю, что у вас уже есть Python на вашем компьютере, если у вас его еще нет, вы можете загрузить Python на веб-сайте Python (www.python.org) и установить его на свой компьютер, в противном случае вы можете использовать Anaconda, скачав его по адресу веб-сайт Anaconda (https://www.anaconda.com/products/individual) и установите его на свой компьютер.

Anaconda — это набор инструментов для обработки и анализа данных, с которым вы можете получить другое программное обеспечение, включая Python, в комплекте с установщиком файлов Anaconda. Программное обеспечение — это Python, Spyder, jupyter-notebook и библиотеки Python. Преимуществом использования Anaconda является простота, а недостатком является большой размер файла установщика, например Anaconda для 64-разрядного графического установщика Windows составляет 477 МБ.

Здесь я использую Linux, поэтому здесь я покажу экран Linux. За исключением некоторых инструкций в терминале или командной строке C, исходный код Flask одинаков в Linux или других основных операционных системах, Windows или Mac OS, поэтому вы можете следовать исходному коду, независимо от того, являетесь ли вы пользователем Linux, пользователем Windows или пользователем Mac OS.

III.Установка Flask
Мы разработаем наш проект в каталоге «jumlah_new», но вы, конечно, можете назвать его по-другому. В каталоге «jumlah_new» мы создаем каталог «venv» как виртуальную среду. Мы создаем виртуальную среду перед установкой Flask [3].

В Linux:
$ mkdir jumlah_new
$ cd jumlah_new
$ python3 -m venv venv или $ python -m venv venv

В Windows:
› mkdir jumlah_new
› cd jumlah_new
› py3 -m venv venv

Виртуальная среда полезна для ограничения нашей среды всей средой в нашей операционной системе, поэтому установка не влияет на операционную систему.

Активировать виртуальную среду
Далее активируем нашу виртуальную среду.
В Linux:
$ . venv/bin/активировать

В Windows:
venv\Scripts\activate

Установите Flask
В Linux:
$ pip install flask

В Windows:
› pip install flask

Далее для Windows и Linux будут те же инструкции.
Мы можем протестировать нашу установку Flask с помощью консоли Python, набрав:
import flask.
Если сообщение об ошибке не появляется, Flask установлен правильно.

IV. О приложении CRUD
Теперь у нас есть инструменты для создания приложения с использованием Flask. Прежде чем мы начнем писать код, я хотел бы объяснить, какую программу мы будем создавать. Это простое приложение CRUD, а именно арифметическая операция. Приложение имеет 3 данных для ввода, это значение 1, значение 2 и оператор. Оператор имеет 4 элемента для выбора одного из них: сложение (+), вычитание (-), умножение (*) и деление (/). Два введенных значения затем обрабатываются в зависимости от выбранного оператора и создают примечание, будь то нечетное или четное. Например, мы вводим 4 для значения 1, 5 для значения 2 и * или умножение для оператора, результат равен 20, а примечание — четное. Все входные и выходные данные, включая примечания, хранятся в таблице MariaDB, которую я использую Xampp (www.apachefriends.org), дистрибутив Apache содержит PHP, Perl и MariaDB. Имя таблицы - Penjumlahan. Penjumlahan на индонезийском языке означает дополнение.

Форма заявки ниже:

Существует также страница, отображающая ввод и вывод, и обе они могут быть отредактированы или удалены.

Меню, расположенное на столе, это «Главная», «Входные данные» и «Отображение данных». Home для отображения слова «Home», начальной страницы, Entry Data для отображения формы Entry Data и Display Data для отображения данных в таблице.

V.Hello World, для начала
Теперь пришло время написать наш код, начав писать Hello World в нашем приложении flask для начала. Я учусь из «The Flask Mega tutorial», написанного Мигелем Гринбергом, для создания приложения Hello World [4]. Я предлагаю вам также изучить этот учебник по Flask, потому что он учит нас шаг за шагом с самого начала в деталях.

Сначала войдите в свой корневой каталог (jumlah) и создайте в нем каталог «app». Создайте файл __init__.py в каталоге приложения (app/__init__.py) и напишите в нем следующий код:

from flask import flask
app=flask(__name__)
from app import routes

Затем создайте route.py в каталоге приложения (app/routes.py) и напишите в нем код следующим образом:

from app import app
@app.route("/")
@app.route("/index")
def index():
   return "Hello World"

После этого создайте jumlah_new.py в нашем корневом каталоге и напишите в нем следующий код:

from app import app

Затем, чтобы запустить приложение, установите переменную среды flask_app следующим образом:
$ export flask_app=jumlah_new.py
Затем мы запускаем flask с помощью этой инструкции:
$ flask run

Теперь мы можем запустить приложение, набрав URL в браузере: http://localhost:5000/ или http://127.0.0.1:5000/.

Теперь структура каталога следующая:
jumlah_new
›app
›› __init__.py
›› route.py
› jumlah_new.py
› Венв

VI. Создание приложения CRUD
Представление Hello World — это начальное представление или представление Home, и мы помещаем его в /index или /, поэтому в веб-браузере URL-адрес http: //127.0.0.1:5000 или http://127.0.0.1:5000/index. Мы можем изменить Hello World на Home и поместить его посередине экрана, чтобы главный экран был:

Не забывайте, что корневой каталог, который мы используем, называется jumlah_new.

VI.a. Создать форму ввода
Сначала мы создаем форму ввода и результат, как показано на рисунке 5 выше, но я снова вставляю ее сюда следующим образом:

Чтобы сделать такую ​​форму, мы используем метод render_template из Flask. Мы также используем расширение Flask-wtf, чтобы помочь нам в создании компонентов формы, таких как метка, кнопка и текстовое поле. Flask-wtf устанавливается в терминале или командной строке с помощью инструкции: pip install flask-wtf.

Мы также создаем файл, содержащий класс jumlah_new/app/frm_entry.py, внутри которого находятся компоненты формы, и компоненты используются маршрутами и отображаются с помощью файла представления, это jumlah_new/app/templates/frm_entry.html.

Для просмотра файлов мы сохраняем их в каталоге jumlah_new/app/templates. Просмотр файлов с использованием jinja, который является шаблонизатором по умолчанию в Flask.

Файлы создаются следующим образом:

jumlah_new
/ app
›/templates
›› frm_entry.html
› route.py
› __init__.py
› frm_entry.py
> /venv
config.py
jumlah_new.py

а. jumlah_new/app/__init__.py

from flask import Flask
from config import Config
app=Flask(__name__)
app.config.from_object(Config)
from app import routes

__init__.py — это начальный файл, который находится в каждом запущенном приложении, этот файл всегда выполняется в начале.
Примечания к некоторым кодам следующие:
из flask import Flask
Примечания: Импортируйте метод или класс Flask, которые существуют в среде flask.

из конфигурации импортировать конфигурацию
Примечания: Импортируйте конфигурацию класса, которая существует в файле jumlah_new/config.py.

app=Flask(__name__)
Примечания. Загрузить Flask(__name__) и сохранить с помощью переменной приложения

app.config.from_object(Config)
Примечания. Используйте конфигурацию класса (объект), которая существует в файле jumlah_new/config.py.

из маршрутов импорта приложений
Примечания: загружать маршруты, существующие в файле маршрутов.

б. jumlah_new/config.py

import os
class Config(object):
    SECRET_KEY=os.environ.get("SECRET_KEY") or "you-will-never-               guess"

config.py необходим для обеспечения безопасности формы. Отступ неправильный, особенно слово «угадай», потому что редактор не разрешает мне добавлять отступ перед словом «угадай», пожалуйста, поймите это :-). Это также может произойти для следующего другого исходного кода.

в. jumlah_new/jumlah_new.py

from app import app

Этот файл вызывается для запуска сервера flask перед запуском приложения.

д. jumlah_new/app/routes.py

from flask import render_template
from app import app
from app.frm_entry import EntryForm
@app.route("/")
@app.route("/index")
def index():
    form=EntryForm()
    return render_template("frm_entry.html",title="Entry and Result            Form",formnya=form)

route.py — это файл для управления приложением. Мы используем метод render_template из flask, класс EntryForm, который существует в jumlah_new/app/frm_entry.py, и загружаем переменную приложения, которая существует в __ini__.py. render_template для загрузки файла шаблонов, который имеет расширение .html и существует в каталоге jumlah_new/app/templates.
Примечания к некоторым кодам следующие:
from app.frm_entry import EntryForm
Примечания: загрузите класс EntryForm, который существует в jumlah_new/app/frm_entry.py.

@app.route("/")
@app.route("/index")
Примечания: Инструкция будет выполнена в / или /index последнего URL

form=EntryForm()
Примечания: EntryForm — это класс, который вызывается и находится в файле jumlah_new/app/frm_entry.py.

return render_template("frm_entry.html", title="Форма ввода и результатов", formnya=form)
Примечания: Загрузите frm_entry.html в каталог jumlah_new/app/templates. Он также отправляет переменную «title» и переменную «formnya» в frm_entry.html.

e. jumlah_new/app/frm_entry.py

from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, SelectField
from wtforms.validators import DataRequired
class EntryForm(FlaskForm):
    nilai_1=StringField("Value 1", validators=[DataRequired()])
    nilai_2=StringField("Value 2", validators=[DataRequired()])
    operatornya=SelectField("Operator", choices=[("","Choose     Operator"),("*","X"),("+","+"),("-","-"),                                    ("/","/")])
    submit=SubmitField("Save")
    batal=SubmitField("Cancel")

Поскольку мы установили расширение flask_wtf, мы можем использовать его для создания формы. В форме мы используем TextField, Select и Submit Button, а чтобы сделать их доступными, мы импортируем StringField, SubmitField и SelectField из wtforms. В TextField нам нужно проверить, что TextField должен быть заполнен, поэтому мы используем синтаксис validators=[DataRequired()] в каждом создаваемом StringField.

Здесь мы также создаем класс EntryForm (FlaskForm), который импортируется по маршрутам.

ж. jumlah_new/app/templates/frm_entry.html

<DOCTYPE html>
<html>
  <head>
   <title>Entry Form</title>
  </head>
  <body>
    <a href="#">Home</a> <a href="#">Entry Data</a> <a href="#">Display Data</a>
    <h1>Arithmetics</h1>
    <table>
    <form action="" method="post" novalidate>
    <tr>
      <td>{{ formnya.nilai_1.label }}</td><td>:</td>
      <td>{{ formnya.nilai_1(size=20) }}</td>
    </tr>    
    <tr>
      <td>{{ formnya.nilai_2.label }}</td><td>:</td>
      <td>{{ formnya.nilai_2(size=20) }}</td>
    </tr>    
    <tr>
       <td>{{ formnya.operatornya.label }}</td><td>:</td>
       <td>{{ formnya.operatornya }}</td>
    </tr>    
    <tr>
       <td>{{ formnya.submit() }} {{ formnya.batal }}</td>
    </tr>
    </body>   
    </table>
</html>

Мы используем html для отображения веб-формы, а также для этой формы. Как указывалось ранее, мы используем Jinja для просмотра. Jinja имеет синтаксис «{{» и «}}» для вывода переменных, как в исходном коде выше.

После того, как мы напишем весь исходный код, мы можем запустить приложение и, если ошибки нет, мы можем увидеть форму, но форма еще не работает, чтобы сохранить данные и распечатать результат. Нам нужно добавить другой исходный код, чтобы заставить его работать.

VI.b Заставьте форму ввода работать
VI.b.1 Наследование

Прежде чем мы заставим форму ввода работать, сначала мы создадим наследование шаблона. Это файл шаблона, встроенный в другой файл для упрощения работы. Заголовок файла часто может быть встроен в другой файл, если есть изменение в файле заголовка, например, загрузить код Javascript, изменяется только один файл заголовка, и это влияет на файлы, в которые встроен заголовок. Итак, мы делим jumlah_new/app/templates/frm_entry.html на 2 файла, которые становятся header_footer.html и собственно frm_entry.html:

jumlah_new/app/templates/header_footer.html

<DOCTYPE html>
<html>
   <head>
      <title>Entry Form</title>
   </head>
   <body>
   <a href="/">Home</a> | <a href="/frm_entry">Entry Data</a> | <a href="/tampil_data">Display Data</a>
    {% block content %}{% endblock %}
   </body>
</html>

Приведенный выше файл содержит меню, каждое меню имеет следующий URL-адрес:

<a href=”/”>Home</a> | <a href=”/frm_entry”>Entry Data</a> | <a href=”/tampil_data”>Display Data</a>

Шаблон формы заявки сохраняется в jumlah_new/app/templates/frm_entry.html следующим образом:

{% extends "header_footer.html" %}
{% block content %}
    <a href="#">Home</a>
    <a href="#">Entry Data</a> <a href="#">Display Data</a>
    <h1>Arithmetics</h1>
    <table>
    <form action="" method="post" novalidate>
    <tr>
      <td>{{ formnya.nilai_1.label }}</td><td>:</td>
      <td>{{ formnya.nilai_1(size=20) }}</td>
    </tr>    
    <tr>
      <td>{{ formnya.nilai_2.label }}</td><td>:</td>
      <td>{{ formnya.nilai_2(size=20) }}</td>
    </tr>    
    <tr>
       <td>{{ formnya.operatornya.label }}</td><td>:</td>
       <td>{{ formnya.operatornya }}</td>
    </tr>    
    <tr>
       <td>{{ formnya.submit() }} {{ formnya.batal }}</td>
    </tr>
{% endblock %}

Форма ввода представляет собой таблицу, выполненную в формате HTML с использованием тега ‹table›. Он использует Jinja. Переменная печатается с использованием символов {{ и }}.

VI.b.2 Сохранение данных из формы ввода
Данные, введенные в форму ввода, сохраняются в таблице Penjumlahan, созданной с использованием базы данных MariaDB, следующим образом:
Имя таблицы: penjumlahan< br /> Поля: id (int) первичный ключ, value_1 (double), value_2 (double), оператор (varchar), результат (double), примечание (varchar)

Затем нам нужно расширение Flask-MySQL, поэтому мы устанавливаем Flask-MySQL версии 1.5.2, используя PIP. В настоящее время, когда эта статья написана, последняя версия Flask-MySQL, которую я использую, еще не работает, но, возможно, когда вы будете читать эту статью, последняя версия будет более обновленной, чем сейчас, и ее можно будет использовать.
Команда для установки Flask-MySQL версия 1.5.2 находится здесь (введите без $):
$ pip install Flask-MySQL==1.5.2
И команда для установки последней версии Flask-MySQL находится здесь:
$ pip установить Flask-MySQL.

Сохраняем введенные данные, результат и примечание в таблицу. Результат зависит от выбранного оператора: если мы выбираем «+», результатом будет значение_1 + значение_2, если мы выбираем «*», результатом будет значение_1 x значение_2 и т. д.
Мы также решаем, является ли результат Четное, нечетное или нулевое.
Мы добавляем функцию frm_entry в route.py.
jumlah_new/app/routes.py станет:

from flask import render_template, request, url_for, redirect
from flaskext.mysql import MySQL
from app import app
from app.frm_entry import EntryForm
# Connecting database
app.config["MYSQL_DATABASE_HOST"]="localhost"
app.config["MYSQL_DATABASE_USER"]="root"
app.config["MYSQL_DATABASE_PASSWORD"]="opansan63"
app.config["MYSQL_DATABASE_DB"]="test"
app.config["MYSQL_PORT"]="3306"
# Preparing variable on mysqlnya
mysqlnya=MySQL(app)
mysqlnya.init_app(app)
@app.route("/")
def home():
    return render_template("home.html", title="Home")
@app.route("/frm_entry", methods=["GET","POST"])
def frm_entry():
    resultnya=0
    rem=""
    xvalue_1=0
    xvalue_2=0
    xoperator=""    
    
    formnya=EntryForm()
    
    # Save inputted data to variables
    if request.method=="POST":
        details=request.form
        xvalue_1=details["value_1"]
        xvalue_2=details["value_2"]
        xoperator=details["operatornya"]
    
    # Processing result
    if xoperator=="+":
       resultnya=int(xvalue_1)+int(xvalue_2)
    elif xoperator=="-":
       resultnya=int(xvalue_1)-int(xvalue_2)
    elif xoperator=="/":
       resultnya=int(xvalue_1)/int(xvalue_2)
    elif xoperator=="*":
       resultnya=int(xvalue_1)*int(xvalue_2)    
   
    # Processing remarks, Even, Odd or Zero
    if resultnya==0:
        rem="Zero"
    elif resultnya % 2 ==0:    
        rem="Even"
    elif resultnya % 2==1:
         rem="Odd"    
    else:
        rem=""
# Save data        
    cur=mysqlnya.connect().cursor()
    cur.execute("insert into penjumlahan (value_1,value_2,operator,result, remark) values (%s,%s,%s,%s,%s)",((xvalue_1,xvalue_2,xoperator,resultnya,rem)))
    cur.connection.commit()
    cur.close()
    
    return render_template("frm_entry.html", title="Nilai", formnya=formnya, xresultnya=resultnya, remnya=rem)

Некоторые важные замечания к приведенному выше исходному коду:

from flask import render_template, request, url_for, redirect
from flaskext.mysql import MySQL
from app import app
from app.frm_entry import EntryForm

Примечания: мы импортируем render_template, url_for, request и redirect в flask. url_for и редирект пока не используем, позже воспользуемся. Мы также импортируем класс EntryForm из app/frm_entry.py. Мы также импортируем MySQL из flaskext.mysql.

# Connecting database
app.config["MYSQL_DATABASE_HOST"]="localhost"
app.config["MYSQL_DATABASE_USER"]="root"
app.config["MYSQL_DATABASE_PASSWORD"]="opansan63"
app.config["MYSQL_DATABASE_DB"]="test"
app.config["MYSQL_PORT"]="3306"

Примечания: мы подключаем базу данных, настроив некоторые параметры: хост, пользователь, пароль, имя базы данных и порт. 3306 — стандартный порт для MariaDB. Перед запуском приложения не забудьте сначала запустить базу данных. Для пользователя Xampp сначала запустите Xampp.

# Preparing variable on mysqlnya
mysqlnya=MySQL(app)
mysqlnya.init_app(app)

Примечания: мы готовим переменную mysqlnya, которая будет использоваться для сохранения, редактирования, отображения и удаления данных.

# Save data        
    cur=mysqlnya.connect().cursor()
    cur.execute("insert into penjumlahan (value_1,value_2,operator,result, remark) values (%s,%s,%s,%s,%s)",((xvalue_1,xvalue_2,xoperator,resultnya,rem)))
    cur.connection.commit()
    cur.close()

Примечания: Для сохранения данных мы подключаемся к базе данных с помощью переменной cur, а затем выполняем запрос на вставку.

Мы отправляем переменные Result и Remark из routers.py (xresultnya и remnya) в форму ввода, поэтому jumlah_new/app/templates/frm_entry.html теперь выглядит следующим образом:

{% extends "header_footer.html" %}
{% block content %}
    <a href="#">Home</a> <a href="#">Entry Data</a>
    <a href="#">Display Data</a>
    <h1>Arithmetics</h1>
    <table>
    <form action="frm_entry" method="post" novalidate>
    {{ formnya.hidden_tag()}}
    <tr>
      <td>{{ formnya.value_1.label }}</td><td>:</td>
      <td>{{ formnya.value_1(size=20) }}</td>
    </tr>    
    <tr>
      <td>{{ formnya.value_2.label }}</td><td>:</td>
      <td>{{ formnya.value_2(size=20) }}</td>
    </tr>    
    <tr>
       <td>{{ formnya.operatornya.label }}</td><td>:</td>
       <td>{{ formnya.operatornya }}</td>
    </tr>
    <tr>
       <td>Result</td><td>:</td><td>{{ xresultnya }}</td>
    </tr>     
    <tr>
       <td>Remark</td><td>:</td><td>{{ remnya }}</td>
    </tr>
    <tr>
       <td>{{ formnya.submit() }} {{ formnya.batal }}</td>
    </tr>
{% endblock %}

Перед запуском приложения не забудьте запустить базу данных.

VI.c Отображение данных

Внешний вид отображаемых данных мы создадим следующим образом:

Данные, которые мы сохраняем в таблице, нужно отображать, поэтому мы создаем модуль отображения данных в виде таблицы. Мы получаем доступ к отображению данных через меню Display data.

В jumlah_new/app/routes.py мы создаем функцию tampil_data(), у которой есть запрос на отображение всех записей из таблицы Penjumlahan. Результат представляет собой массив и отправляется на просмотр или в файл шаблона. Мы также создаем новый файл для просмотра, а именно tampil_data.html, расположенный в jumlah_new/app/templates.

Функция tampil_data в route.py выглядит следующим образом:

# ...
# above is other codes 
@app.route("/tampil_data")    
def tampil_data():
    formnya=EntryForm()     
       
    cur=mysqlnya.connect().cursor()
    cur.execute("select * from penjumlahan")
    hasilnya=cur.fetchall()    
    return render_template("tampil_data.html", title="Tampil Data",hasilnya=hasilnya,no=1)

В приведенном выше исходном коде есть SQL для отображения всех записей в таблице Penjumlahan.

Полный файл route.py теперь выглядит следующим образом:

from flask import render_template, request, url_for, redirect
from flaskext.mysql import MySQL
from app import app
from app.frm_entry import EntryForm
# Connecting database
app.config["MYSQL_DATABASE_HOST"]="localhost"
app.config["MYSQL_DATABASE_USER"]="root"
app.config["MYSQL_DATABASE_PASSWORD"]="opansan63"
app.config["MYSQL_DATABASE_DB"]="test"
app.config["MYSQL_PORT"]="3306"
# Preparing variable on mysqlnya
mysqlnya=MySQL(app)
mysqlnya.init_app(app)
@app.route("/")
def home():
    return render_template("home.html", title="Home")
@app.route("/frm_entry", methods=["GET","POST"])
def frm_entry():
    resultnya=0
    rem=""
    xvalue_1=0
    xvalue_2=0
    xoperator=""
    
    formnya=EntryForm()
    
    # Save inputted data to variables
    if request.method=="POST":
        details=request.form
        xvalue_1=details["value_1"]
        xvalue_2=details["value_2"]
        xoperator=details["operatornya"]
    
    # Processing result
    if xoperator=="+":
       resultnya=int(xvalue_1)+int(xvalue_2)
    elif xoperator=="-":
       resultnya=int(xvalue_1)-int(xvalue_2)
    elif xoperator=="/":
       resultnya=int(xvalue_1)/int(xvalue_2)
    elif xoperator=="*":
       resultnya=int(xvalue_1)*int(xvalue_2)
    else:
       resultnya=0 
   
    # Processing remarks, Even, Odd or Zero
    if resultnya % 2 ==0:    
        rem="Even"
    elif resultnya % 2==1:
        rem="Odd"
    else:
        rem="Zero"
# Save data        
    cur=mysqlnya.connect().cursor()
    cur.execute("insert into penjumlahan (value_1,value_2,operator,result, remark) values (%s,%s,%s,%s,%s)",((xvalue_1,xvalue_2,xoperator,resultnya,rem)))
    cur.connection.commit()
    cur.close()
    
    return render_template("frm_entry.html", title="Nilai", formnya=formnya, xresultnya=resultnya, remnya=rem)
@app.route("/tampil_data")    
def tampil_data():
    formnya=EntryForm()     
       
    cur=mysqlnya.connect().cursor()
    cur.execute("select * from penjumlahan")
    hasilnya=cur.fetchall()    
    return render_template("tampil_data.html", title="Tampil Data",hasilnya=hasilnya,no=1)

Представление отображения jumlah_new/app/templates/tampil_data.html выглядит следующим образом:

{% extends "header_footer.html" %}
{% block content %}    
  <h1>Arithmetic</h1>
  <table border=1>
  <th>No</th><th>Value 1</th><th>Value 2</th><th>Operator</th>   <th>Result</th><th>Remark</th><th>Options</th>
 {% for rows in hasilnya %}
    <tr>
      <td>{{ loop.index }}</td><td>{{ rows[1] }}</td><td>{{ rows[2]   }}</td>
      <td>{{ rows[3] }}</td><td>{{ rows[4] }}</td>
      <td>{{ rows[5] }}</td><td><a href="{{   url_for('frm_edit_data',id=rows[0])}}">Edit</a> | 
                                <a href="{{ url_for('delete_data',id=rows[0])}}" onClick="return asking()">Delete</a>
  </td>
 </tr>  
{% endfor %}
</table>
{% endblock %}

Мы используем итерацию для печати данных и помещаем их в таблицу. Каждые данные мы печатаем, используя номер индекса, строки [1] для значения 1, строки [2] для значения 2, строки [3] для оператора, строки [4] для результата и строки [5] для примечания. Мы предоставляем ссылку для удаления данных. Такая ссылка является функцией в router.py. Перед удалением данных или удалением записи мы подтверждаем пользователю, действительно ли он хочет удалить их или отменить их, используя Javascript, и сохраняем их в header_footer.html, так что теперь header_footer.html становится:

<DOCTYPE html>
<html>
   <head>
      <title>Entry Form</title>
      <script>
      function asking()
       {
         askingnya=confirm("Are you sure to delete this record ?");         
         if (askingnya==true)
           {
             return True;             
           }
        else
           {
             return False;             
           }              
       }
      </script>
   </head>
   <body>
     <a href="/">Home</a> | <a href="/frm_entry">Entry Data</a> | <a href="/display_data">Display Data</a>
     {% block content %}{% endblock %}
   </body>
</html>

В приведенном выше исходном коде мы вставляем JavaScript между тегами ‹script› и ‹/script›. Он использует функцию запроса. Если подтверждение в порядке, оно вернет True, что означает удаление записи, а если подтверждение Cancel, оно вернет false, что означает, что запись отменена или не удалена. Но на моем компе при последнем запуске такая функция еще не работает, точно не знаю, может есть внешнее влияние типа настроек браузера.

VI.d Редактирование данных

В таблице отображаемых данных у нас есть 2 опции: «редактировать» и «удалить». «Редактировать» отображает выбранные данные или запись для редактирования, а затем сохраняет их.

Во-первых, нам нужно создать функцию frm_edit_data в файле route.py. Эта функция помимо отображения выбранных данных также сохраняет отредактированные данные. Нам также нужно создать форму редактирования html в каталоге шаблонов.

Функция frm_edit_data в route.py выглядит следующим образом:

@app.route("/frm_edit_data/<id>",methods=["GET","POST"])
def frm_edit_data(id):
    cur=mysqlnya.connect().cursor()
    form=EntryForm()
    cur.execute("select * from penjumlahan where id='"+id+"'")
    hasilnya=cur.fetchall()    
    for rows in hasilnya:
        xvalue_1=rows[1]
        xvalue_2=rows[2]
        xoperator=rows[3]
        xresult=rows[4]
        xremark=rows[5]
 
    if request.method=="POST":             
       details=request.form
       xvalue_1=details["value_1"]
       xvalue_2=details["value_2"]
       xoperator=details["operatornya"]
       
       # Processing input to make a result
       if xoperator=="+":
          xresult=float(xvalue_1)+float(xvalue_2)
       elif xoperator=="-":
          xresult=float(xvalue_1)-float(xvalue_2)
       elif xoperator=="/":
          xresult=float(xvalue_1)/float(xvalue_2)
       elif xoperator=="*":
           xresult=float(xvalue_1)*float(xvalue_2)
       else:
           xresult=0
        
       # Menentukan Ganjil atau Genap
       if xresult % 2 ==0:
          xremark="Genap"
       elif xresult % 2==1:
          xremark="Ganjil"
       else:
          xremark="Nol"   
       
       cur=mysqlnya.connect().cursor()
       #cur.execute("update penjumlahan set value_1='"+xnilai_1+"'"+
       #            ",value_2='"+xnilai_2+"'"+",operator='"+xoperator+"'"+
       #            ",result='"+hasil+"'"+",remark='"+xremark+"'"+"where id='"+id+"'")
       
       cur.execute ("update penjumlahan set value_1=%s,value_2=%s,operator=%s,result=%s,remark=%s where id= %s",
                    ((xvalue_1,xvalue_2,xoperator,xresult,xremark,id)))
       cur.connection.commit()
       cur.close()
    else:   
       form.value_1.data=xvalue_1    
       form.value_2.data=xvalue_2
       form.operatornya.data=xoperator          
    
    return render_template("frm_edit.html", title="Edit   Data",znilai_1=xvalue_1,form=form,
    ketnya=xremark,hasilnya=xresult)

Несколько важных замечаний:

@app.route(“/frm_edit_data/<id>”,methods=[“GET”,”POST”])

Приведенный выше код представляет собой URL-адрес с идентификатором, использующим методы get или post. id получается из отображаемых данных просмотра, это первичный ключ в таблице Penjumlahan.

cur.execute("select * from penjumlahan where id='"+id+"'")
    hasilnya=cur.fetchall()    
    for rows in hasilnya:
        xvalue_1=rows[1]
        xvalue_2=rows[2]
        xoperator=rows[3]
        xresult=rows[4]
        xremark=rows[5]    

Приведенный выше код представляет собой запрос для получения данных, где id выбран id. Результатом является только одна запись, в которой мы используем некоторые переменные для сохранения данных: xvalue_1 для сохранения value_1, xvalue_2 для value_2, xoperator для оператора, xresult для результата и xremark для примечания.

if request.method=="POST":       
       
       details=request.form
       xvalue_1=details["value_1"]
       xvalue_2=details["value_2"]
       xoperator=details["operatornya"]
       
       # Processing input data to make a result
       if xoperator=="+":
          xresult=float(xvalue_1)+float(xvalue_2)
       elif xoperator=="-":
          xresult=float(xvalue_1)-float(xvalue_2)
       elif xoperator=="/":
          xresult=float(xvalue_1)/float(xvalue_2)
       elif xoperator=="*":
           xresult=float(xvalue_1)*float(xvalue_2)
       else:
           xresult=0
        
       # Menentukan Ganjil atau Genap
       if xresult % 2 ==0:
          xremark="Even"
       elif xresult % 2==1:
          xremark="Odd"
       else:
          xremark="Zero"   
       
       cur=mysqlnya.connect().cursor()
       #cur.execute("update penjumlahan set value_1='"+xnilai_1+"'"+
       #            ",value_2='"+xnilai_2+"'"+",operator='"+xoperator+"'"+
       #            ",result='"+hasil+"'"+",remark='"+xremark+"'"+"where id='"+id+"'")
       
       cur.execute ("update penjumlahan set value_1=%s,value_2=%s,operator=%s,result=%s,remark=%s where id= %s",
                    ((xvalue_1,xvalue_2,xoperator,xresult,xremark,id)))
       cur.connection.commit()
       cur.close()
    else:   
       form.value_1.data=xvalue_1    
       form.value_2.data=xvalue_2
       form.operatornya.data=xoperator

Приведенный выше код выполняется, когда пользователь нажимает кнопку отправки или сохранения в форме редактирования. Затем снова обрабатывается номер результата расчета, а также снова обрабатывается примечание. После этого таблица Penjumlahan обновляется текущим значением, результатом и примечанием. Если кнопка отправки не нажата, то номер остается прежним без изменений.

Для редактирования шаблона мы используем /jumlah_new/app/templates/frm_edit.html исходный код следующим образом:

{% extends "header_footer.html" %}
{% block content %}
<h1>Aritmetika</h1>
<a href="http://localhost:5000/frm_tampil">Tampil Data</a>
<table>
<form action="" method="post" novalidate>
{{ form.hidden_tag() }}
<tr>
  <td>{{ form.value_1.label}}</td><td>:</td>
  <td>{{ form.value_1(size=20) }}</td>
</tr>
<tr>
  <td>{{ form.value_2.label}}</td><td>:</td>
  <td>{{ form.value_2(size=20) }}</td>
</tr>
<tr>
  <td>{{ form.operatornya.label }}</td><td>:</td>
  <td>{{ form.operatornya }}</td>
</tr>
<tr>
  <td>{{ form.submit() }}</td>
</tr>
</table>
<table>
<tr>
<td>Result</td><td>:</td><td>{{ hasilnya }}</td>
</tr>
<tr>
<td>Remarks</td><td>:</td><td>{{ ketnya }}</td>
</tr>
</table>
{% endblock %}

Форма редактирования аналогична форме ввода, но форма редактирования заполняется данными, которые мы выбираем из таблицы отображаемых данных.

Некоторые замечания следующим образом:

<tr>
<td>Result</td><td>:</td><td>{{ hasilnya }}</td>
</tr>
<tr>
<td>Remarks</td><td>:</td><td>{{ ketnya }}</td>
</tr>

Приведенный выше код предназначен для просмотра результатов и замечаний, где hasilnya и ketnya берутся из route.py.

VI.e Удаление данных

Мы можем удалить запись, щелкнув ссылку «Удалить» в таблице данных отображения. Перед удалением данных есть подтверждение. Мы создаем delete_data в route.py следующим образом:

@app.route("/delete_data/<id>", methods=["GET","POST"])
def delete_data(id):
    cur=mysqlnya.connect().cursor()
    cur.execute("delete from penjumlahan where id='"+id+"'")
    cur.connection.commit()
    cur.close()    
    return redirect(url_for("display_data"))

В приведенном выше коде есть запрос на удаление выбранной записи. После того, как мы удалили запись с помощью cur.connection.commit(), программа переходит к отображению таблицы данных с помощью метода url_for, который мы импортируем в первой строке route.py.

Теперь полный route.py выглядит следующим образом:

from flask import render_template, request, url_for, redirect
from flaskext.mysql import MySQL
from app import app
from app.frm_entry import EntryForm
# Connecting database
app.config["MYSQL_DATABASE_HOST"]="localhost"
app.config["MYSQL_DATABASE_USER"]="root"
app.config["MYSQL_DATABASE_PASSWORD"]="opansan63"
app.config["MYSQL_DATABASE_DB"]="test"
app.config["MYSQL_PORT"]="3306"
# Preparing variable on mysqlnya
mysqlnya=MySQL(app)
mysqlnya.init_app(app)
@app.route("/")
def home():
    return render_template("home.html", title="Home")
@app.route("/frm_entry", methods=["GET","POST"])
def frm_entry():
    resultnya=0
    rem=""
    xvalue_1=0
    xvalue_2=0
    xoperator=""    
    
    formnya=EntryForm()
    
    # Save inputted data to variables
    if request.method=="POST":
        details=request.form
        xvalue_1=details["value_1"]
        xvalue_2=details["value_2"]
        xoperator=details["operatornya"]
    
    # Processing result
    if xoperator=="+":
       resultnya=int(xvalue_1)+int(xvalue_2)
    elif xoperator=="-":
       resultnya=int(xvalue_1)-int(xvalue_2)
    elif xoperator=="/":
       resultnya=int(xvalue_1)/int(xvalue_2)
    elif xoperator=="*":
       resultnya=int(xvalue_1)*int(xvalue_2)    
   
    # Processing remarks, Even, Odd or Zero
    if resultnya==0:
        rem="Zero"
    elif resultnya % 2 ==0:    
        rem="Even"
    elif resultnya % 2==1:
         rem="Odd"    
    else:
        rem=""
# Save data        
    cur=mysqlnya.connect().cursor()
    cur.execute("insert into penjumlahan (value_1,value_2,operator,result, remark) values (%s,%s,%s,%s,%s)",((xvalue_1,xvalue_2,xoperator,resultnya,rem)))
    cur.connection.commit()
    cur.close()
    
    return render_template("frm_entry.html", title="Nilai", formnya=formnya, xresultnya=resultnya, remnya=rem)
@app.route("/display_data")    
def display_data():
    formnya=EntryForm()     
       
    cur=mysqlnya.connect().cursor()
    cur.execute("select * from penjumlahan")
    hasilnya=cur.fetchall()    
    return render_template("tampil_data.html", title="Tampil Data",hasilnya=hasilnya,no=1)
@app.route("/frm_edit_data/<id>",methods=["GET","POST"])
def frm_edit_data(id):
    cur=mysqlnya.connect().cursor()
    form=EntryForm()
    cur.execute("select * from penjumlahan where id='"+id+"'")
    hasilnya=cur.fetchall()    
    for rows in hasilnya:
        xvalue_1=rows[1]
        xvalue_2=rows[2]
        xoperator=rows[3]
        xresult=rows[4]
        xremark=rows[5]    
        
    if request.method=="POST":       
       
       details=request.form
       xvalue_1=details["value_1"]
       xvalue_2=details["value_2"]
       xoperator=details["operatornya"]
       
       # Memproses hasil    
       if xoperator=="+":
          xresult=float(xvalue_1)+float(xvalue_2)
       elif xoperator=="-":
          xresult=float(xvalue_1)-float(xvalue_2)
       elif xoperator=="/":
          xresult=float(xvalue_1)/float(xvalue_2)
       elif xoperator=="*":
           xresult=float(xvalue_1)*float(xvalue_2)
       else:
           xresult=0
        
       # Menentukan Ganjil atau Genap
       if xresult % 2 ==0:
          xremark="Even"
       elif xresult % 2==1:
          xremark="Odd"
       else:
          xremark="Zero"   
       
       cur=mysqlnya.connect().cursor()
       #cur.execute("update penjumlahan set value_1='"+xnilai_1+"'"+
       #            ",value_2='"+xnilai_2+"'"+",operator='"+xoperator+"'"+
       #            ",result='"+hasil+"'"+",remark='"+xremark+"'"+"where id='"+id+"'")
       
       cur.execute ("update penjumlahan set value_1=%s,value_2=%s,operator=%s,result=%s,remark=%s where id= %s",
                    ((xvalue_1,xvalue_2,xoperator,xresult,xremark,id)))
       cur.connection.commit()
       cur.close()
    else:   
       form.value_1.data=xvalue_1    
       form.value_2.data=xvalue_2
       form.operatornya.data=xoperator          
    
    return render_template("frm_edit.html", title="Edit Data",znilai_1=xvalue_1,form=form,
                           ketnya=xremark,hasilnya=xresult)
@app.route("/delete_data/<id>", methods=["GET","POST"])
def delete_data(id):
    cur=mysqlnya.connect().cursor()
    cur.execute("delete from penjumlahan where id='"+id+"'")
    cur.connection.commit()
    cur.close()    
    return redirect(url_for("display_data"))

Исходный код доступен на https://github.com/sofwanbl/flask_mariadb_crud.

VII. Заключение

Мы уже создали приложение Create Read Update and Delete (CRUD) с использованием Flask и MariaDB. CRUD очень часто используется во многих приложениях и обычно использует файл или базу данных для управления данными. Есть несколько запросов с использованием SQL, которые мы используем здесь, а именно: создание или сохранение данных с помощью вставки в, чтение с помощью выбора, обновление с помощью обновления и удаление с помощью удаления.

После создания этого приложения мы можем разработать другое приложение с использованием Flask, используя и модифицируя созданный нами исходный код.

VIII. Ссылка

[1] Предисловие, документация Flask, https://flask.palletsprojects.com/en/2.0.x/foreword/#what-does-micro-mean, 29 августа 2021 г.
[2] Майкл Байер. mike(&)zzzcomputing.com, Документация по SQL Alchemy, https://www.sqlalchemy.org/, 29 августа 2021 г.
[3] Установка Flask, https://flask.palletsprojects.com/en /2.0.x/установка/, 07 окт 2021