Статьи

Создание веб-приложения с нуля с использованием Python Flask и MySQL: Часть 3

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

Давайте начнем с клонирования предыдущей части для учебника из GitHub .

1
git clone https://github.com/jay3dec/PythonFlaskMySQLApp_Part2.git

После того, как исходный код был клонирован, перейдите в каталог проекта и запустите веб-сервер.

1
2
cd PythonFlaskMySQLApp_Part2
python app.py

Укажите в браузере http: // localhost: 5002 /, и приложение должно быть запущено.

Домашняя страница приложения Bucket List

Мы начнем с создания интерфейса для вошедшего в систему пользователя для добавления элементов списка корзины. Перейдите в папку templates внутри каталога проекта и создайте файл с именем addWish.html . Откройте addWish.html и добавьте следующий HTML-код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<!DOCTYPE html>
<html lang=»en»>
 
<head>
    <title>Python Flask Bucket List App</title>
 
 
    <link href=»http://getbootstrap.com/dist/css/bootstrap.min.css» rel=»stylesheet»>
 
    <link href=»http://getbootstrap.com/examples/jumbotron-narrow/jumbotron-narrow.css» rel=»stylesheet»>
 
    <script src=»../static/js/jquery-1.11.2.js»></script>
 
 
</head>
 
<body>
 
    <div class=»container»>
        <div class=»header»>
            <nav>
                <ul class=»nav nav-pills pull-right»>
                    <li role=»presentation» class=»active»><a href=»#»>Add Item</a>
                    </li>
                    <li role=»presentation»><a href=»/logout»>Logout</a>
                    </li>
                </ul>
            </nav>
            <h3 class=»text-muted»>Python Flask App</h3>
        </div>
        <section>
            <form class=»form-horizontal» method=»post» action=»/addWish»>
                <fieldset>
 
                    <!— Form Name —>
                    <legend>Create Your Wish</legend>
 
                    <!— Text input—>
                    <div class=»form-group»>
                        <label class=»col-md-4 control-label» for=»txtTitle»>Title</label>
                        <div class=»col-md-4″>
                            <input id=»txtTitle» name=»inputTitle» type=»text» placeholder=»placeholder» class=»form-control input-md»>
                        </div>
                    </div>
 
                    <!— Textarea —>
                    <div class=»form-group»>
                        <label class=»col-md-4 control-label» for=»txtPost»>Post</label>
                        <div class=»col-md-4″>
                            <textarea class=»form-control» id=»txtPost» name=»inputDescription»></textarea>
                        </div>
                    </div>
 
                    <!— Button —>
                    <div class=»form-group»>
                        <label class=»col-md-4 control-label» for=»singlebutton»></label>
                        <div class=»col-md-4″>
                            <input id=»singlebutton» name=»singlebutton» class=»btn btn-primary» type=»submit» value=»Publish» />
                        </div>
                    </div>
 
                </fieldset>
            </form>
 
        </section>
        <footer class=»footer»>
            <p>&copy;
        </footer>
 
    </div>
</body>
 
</html>

Откройте app.py и добавьте новый маршрут и метод для отображения страницы Add Wish .

1
2
3
@app.route(‘/showAddWish’)
def showAddWish():
    return render_template(‘addWish.html’)

Откройте userHome.html и добавьте новый пункт меню для ссылки на страницу Add Wish .

1
<li role=»presentation»><a href=»/showAddWish»>Add Wish</a></li>

Сохраните изменения и перезапустите сервер. Укажите в браузере http: // localhost: 5002 и войдите в систему, используя действующий адрес электронной почты и пароль. После входа нажмите на ссылку « Добавить желание», и у вас должна появиться страница «Добавить желание».

Добавить элемент списка ковша

Чтобы добавить элементы в список tbl_wish , нам нужно создать таблицу с именем tbl_wish .

1
2
3
4
5
6
7
8
CREATE TABLE `tbl_wish` (
  `wish_id` int(11) NOT NULL AUTO_INCREMENT,
  `wish_title` varchar(45) DEFAULT NULL,
  `wish_description` varchar(5000) DEFAULT NULL,
  `wish_user_id` int(11) DEFAULT NULL,
  `wish_date` datetime DEFAULT NULL,
  PRIMARY KEY (`wish_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;

tbl_wish будет title , description и ID пользователя, который создал желание.

Затем нам нужно создать хранимую процедуру MySQL для добавления элементов в таблицу tbl_wish .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
USE `BucketList`;
DROP procedure IF EXISTS `BucketList`.`sp_addWish`;
 
DELIMITER $$
USE `BucketList`$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_addWish`(
    IN p_title varchar(45),
    IN p_description varchar(1000),
    IN p_user_id bigint
)
BEGIN
    insert into tbl_wish(
        wish_title,
        wish_description,
        wish_user_id,
        wish_date
    )
    values
    (
        p_title,
        p_description,
        p_user_id,
        NOW()
    );
END$$
 
DELIMITER ;
;

Создайте метод с именем addWish в app.py

1
2
3
@app.route(‘/addWish’,methods=[‘POST’])
def addWish():
    # Code will be here

Поскольку мы будем публиковать данные в этом методе, мы явно объявили их по определенному маршруту.

Когда выполняется вызов метода addWish , нам нужно проверить, является ли это подлинным вызовом, проверив, существует ли user переменной сеанса. Как только мы проверим сессию, мы прочитаем опубликованный title и description .

1
2
3
_title = request.form[‘inputTitle’]
_description = request.form[‘inputDescription’]
_user = session.get(‘user’)

Как только мы получим необходимые входные значения, мы откроем соединение MySQL и вызовем хранимую процедуру sp_addWish .

1
2
3
4
conn = mysql.connect()
cursor = conn.cursor()
cursor.callproc(‘sp_addWish’,(_title,_description,_user))
data = cursor.fetchall()

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

1
2
3
4
5
if len(data) is 0:
    conn.commit()
    return redirect(‘/userHome’)
else:
    return render_template(‘error.html’,error = ‘An error occurred!’)

Вот полный метод addWish .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@app.route(‘/addWish’,methods=[‘POST’])
def addWish():
    try:
        if session.get(‘user’):
            _title = request.form[‘inputTitle’]
            _description = request.form[‘inputDescription’]
            _user = session.get(‘user’)
 
            conn = mysql.connect()
            cursor = conn.cursor()
            cursor.callproc(‘sp_addWish’,(_title,_description,_user))
            data = cursor.fetchall()
 
            if len(data) is 0:
                conn.commit()
                return redirect(‘/userHome’)
            else:
                return render_template(‘error.html’,error = ‘An error occurred!’)
 
        else:
            return render_template(‘error.html’,error = ‘Unauthorized Access’)
    except Exception as e:
        return render_template(‘error.html’,error = str(e))
    finally:
        cursor.close()
        conn.close()

Сохраните весь исходный код и перезапустите сервер. Укажите в браузере http: // localhost: 5002 и войдите в систему, используя действующий адрес электронной почты и пароль. После входа нажмите на ссылку Добавить желание . Введите title и description для вашего желания и нажмите Опубликовать . При успешном добавлении желания оно должно быть перенаправлено на домашнюю страницу пользователя. Войдите в базу данных MySQL, и у вас должно появиться желание в вашей таблице tbl_wish .

Давайте создадим хранимую процедуру MySQL, которая получит пожелания, созданные пользователем. Он будет принимать ID пользователя в качестве параметра и возвращать набор данных пожеланий, созданных конкретным идентификатором пользователя.

01
02
03
04
05
06
07
08
09
10
11
12
13
USE `BucketList`;
DROP procedure IF EXISTS `sp_GetWishByUser`;
 
DELIMITER $$
USE `BucketList`$$
CREATE PROCEDURE `sp_GetWishByUser` (
IN p_user_id bigint
)
BEGIN
    select * from tbl_wish where wish_user_id = p_user_id;
END$$
 
DELIMITER ;

Далее, давайте создадим метод Python, который будет вызывать хранимую процедуру sp_GetWishByUser чтобы получить пожелания, созданные пользователем. Добавьте метод с именем getWish в app.py

1
2
3
4
5
6
7
8
9
@app.route(‘/getWish’)
def getWish():
    try:
        if session.get(‘user’):
            _user = session.get(‘user’)
        else:
            return render_template(‘error.html’, error = ‘Unauthorized Access’)
    except Exception as e:
        return render_template(‘error.html’, error = str(e))

Как видно из приведенного выше кода, этот метод может быть вызван только с действительным сеансом user . После того, как мы проверим правильность сеанса пользователя, мы создадим соединение с базой данных MySQL и вызовем хранимую процедуру sp_GetWishByUser .

1
2
3
4
5
6
7
_user = session.get(‘user’)
 
# Connect to MySQL and fetch data
con = mysql.connect()
cursor = con.cursor()
cursor.callproc(‘sp_GetWishByUser’,(_user,))
wishes = cursor.fetchall()

После того, как мы получили данные из MySQL, мы проанализируем данные и преобразуем их в dictionary чтобы их было легко вернуть как JSON .

1
2
3
4
5
6
7
8
wishes_dict = []
for wish in wishes:
    wish_dict = {
        ‘Id’: wish[0],
        ‘Title’: wish[1],
        ‘Description’: wish[2],
        ‘Date’: wish[4]}
wishes_dict.append(wish_dict)

После преобразования данных в dictionary мы преобразуем данные в JSON и вернемся.

1
return json.dumps(wishes_dict)

Вот полный метод getWish .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@app.route(‘/getWish’)
def getWish():
    try:
        if session.get(‘user’):
            _user = session.get(‘user’)
 
            con = mysql.connect()
            cursor = con.cursor()
            cursor.callproc(‘sp_GetWishByUser’,(_user,))
            wishes = cursor.fetchall()
 
            wishes_dict = []
            for wish in wishes:
                wish_dict = {
                        ‘Id’: wish[0],
                        ‘Title’: wish[1],
                        ‘Description’: wish[2],
                        ‘Date’: wish[4]}
                wishes_dict.append(wish_dict)
 
            return json.dumps(wishes_dict)
        else:
            return render_template(‘error.html’, error = ‘Unauthorized Access’)
    except Exception as e:
        return render_template(‘error.html’, error = str(e))

Когда домашняя страница пользователя загружена, мы getWish метод getWish с помощью jQuery AJAX и getWish полученные данные в наш HTML. В userHome.html добавьте следующий jQuery AJAX-скрипт:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
<script>
    $(function() {
        $.ajax({
            url: ‘/getWish’,
            type: ‘GET’,
            success: function(res) {
                console.log(res);
            },
            error: function(error) {
                console.log(error);
            }
        });
    });
</script>

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

01
02
03
04
05
06
07
08
09
10
11
[{
    «Date»: «Fri, 23 Jan 2015 23:26:05 GMT»,
    «Description»: «I want to climb Mount Everest»,
    «Id»: 1,
    «Title»: «Climb Everest»
}, {
    «Date»: «Fri, 23 Jan 2015 23:27:05 GMT»,
    «Description»: «I want to jump from top of a mountain»,
    «Id»: 2,
    «Title»: «Bungee Jump»
}]

Теперь нам нужно перебрать данные JSON и связать их с HTML. Мы будем использовать начальную list-group начальной загрузки для отображения элементов списка желаний. Вот основной шаблон для list-group :

1
2
3
4
5
6
<div class=»list-group»>
  <a href=»#» class=»list-group-item active»>
    <h4 class=»list-group-item-heading»>Wish Title</h4>
    <p class=»list-group-item-text»>Wish Description</p>
  </a>
</div>

Добавьте приведенный выше HTML-код в jumbotron div в userHome.html . Вот как это выглядит:

list-group в Доме пользователя

Теперь, что мы сделаем, это создадим показанный выше div list-group динамически для каждой записи списка желаний и jumbotron его в jumbotron div. Внутри обратного вызова успешного вызова функции getWish создайте div, как показано ниже:

1
2
3
4
5
6
7
8
var div = $(‘<div>’)
   .attr(‘class’, ‘list-group’)
   .append($(‘<a>’)
       .attr(‘class’, ‘list-group-item active’)
       .append($(‘<h4>’)
           .attr(‘class’, ‘list-group-item-heading’),
           $(‘<p>’)
           .attr(‘class’, ‘list-group-item-text’)));

Мы будем клонировать вышеприведенный div для создания div list-group для каждого элемента списка желаний. Затем проанализируйте возвращенную строку JSON в объект JavaScript.

1
var wishObj = JSON.parse(res);

Теперь wishObj и для каждого элемента желаний wishObj новый div и добавьте его в jumbotron div.

1
2
3
4
5
6
7
8
var wish = »;
 
$.each(wishObj, function(index, value) {
    wish = $(div).clone();
    $(wish).find(‘h4’).text(value.Title);
    $(wish).find(‘p’).text(value.Description);
    $(‘.jumbotron’).append(wish);
});

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

Домашняя страница пользователя, заполненная пожеланиями

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

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

Исходный код из этого урока доступен на GitHub .

Дайте нам знать ваши мысли в комментариях ниже!