Статьи

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

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

В этой части серии мы увидим, как переключать отображение «нравится / не похоже» и отображать общее количество лайков, полученных по определенному желанию.

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

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

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

1
2
cd PythonFlaskMySQLApp_Part7
python app.py

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

Мы начнем с реализации функции, чтобы показать общее количество подсчетов, которые получил конкретное желание. Когда будет добавлено новое желание, мы сделаем запись в таблицу tbl_likes . Поэтому измените хранимую процедуру MySQL sp_addWish чтобы добавить запись в таблицу tbl_likes .

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
DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_addWish`(
    IN p_title varchar(45),
    IN p_description varchar(1000),
    IN p_user_id bigint,
    IN p_file_path varchar(200),
    IN p_is_private int,
    IN p_is_done int
)
BEGIN
    insert into tbl_wish(
        wish_title,
        wish_description,
        wish_user_id,
        wish_date,
        wish_file_path,
        wish_private,
        wish_accomplished
    )
    values
    (
        p_title,
        p_description,
        p_user_id,
        NOW(),
        p_file_path,
        p_is_private,
        p_is_done
    );
 
    SET @last_id = LAST_INSERT_ID();
    insert into tbl_likes(
        wish_id,
        user_id,
        wish_like
    )
    values(
        @last_id,
        p_user_id,
        0
    );
     
 
END$$
DELIMITER ;

Как видно из приведенного выше кода хранимой процедуры, после вставки желания в таблицу tbl_wish мы tbl_wish последний вставленный ID и вставили данные в таблицу tbl_likes .

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

1
2
3
4
5
6
7
8
9
DELIMITER $$
CREATE DEFINER=`root`@`localhost` FUNCTION `getSum`(
    p_wish_id int
) RETURNS int(11)
BEGIN
    select sum(wish_like) into @sm from tbl_likes where wish_id = p_wish_id;
RETURN @sm;
END$$
DELIMITER ;

Теперь вызовите вышеупомянутую функцию MySQL с именем getSum в хранимой процедуре sp_GetAllWishes чтобы получить общее количество лайков для каждого желания.

1
2
3
4
5
6
7
DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_GetAllWishes`()
BEGIN
    select wish_id,wish_title,wish_description,wish_file_path,getSum(wish_id)
    from tbl_wish where wish_private = 0;
END$$
DELIMITER ;

Измените getAllWishes Python getAllWishes чтобы он включал число подобных. При повторении результата, возвращаемого хранимой процедурой MySQL, включите поле like, как показано ниже:

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

Измените метод JavaScript CreateThumb чтобы создать дополнительный промежуток, который мы будем использовать для отображения одинакового количества.

1
var likeSpan = $(‘<span>’).attr(‘aria-hidden’,’true’).html(‘&nbsp;’+like+’ like(s)’);

И добавьте likeSpan к родительскому абзацу p . Вот модифицированная функция JavaScript CreateThumb .

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
function CreateThumb(id, title, desc, filepath, like) {
    var mainDiv = $(‘<div>’).attr(‘class’, ‘col-sm-4 col-md-4’);
    var thumbNail = $(‘<div>’).attr(‘class’, ‘thumbnail’);
    var img = $(‘<img>’).attr({
        ‘src’: filepath,
        ‘data-holder-rendered’: true,
        ‘style’: ‘height: 150px;
    });
    var caption = $(‘<div>’).attr(‘class’, ‘caption’);
    var title = $(‘<h3>’).text(title);
    var desc = $(‘<p>’).text(desc);
 
 
    var p = $(‘<p>’);
    var btn = $(‘<button>’).attr({
        ‘id’: ‘btn_’ + id,
        ‘type’: ‘button’,
        ‘class’: ‘btn btn-danger btn-sm’
    });
    var span = $(‘<span>’).attr({
        ‘class’: ‘glyphicon glyphicon-thumbs-up’,
        ‘aria-hidden’: ‘true’
    });
 
    var likeSpan = $(‘<span>’).attr(‘aria-hidden’, ‘true’).html(‘&nbsp;’ + like + ‘ like(s)’);
 
    p.append(btn.append(span));
    p.append(likeSpan);
 
 
    caption.append(title);
    caption.append(desc);
    caption.append(p);
 
    thumbNail.append(img);
    thumbNail.append(caption);
    mainDiv.append(thumbNail);
    return mainDiv;
 
 
}

Включите параметр like при вызове JavaScript-функции CreateThumb из успешного обратного вызова вызова jQuery AJAX для /getAllWishes .

1
CreateThumb(data[i].Id,data[i].Title,data[i].Description,data[i].FilePath,data[i].Like)

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

Панель инструментов с лайками

Видя лайки под каждым желанием, не очень понятно, понравился ли зарегистрированному пользователю желание или нет. Таким образом, мы покажем правильное сообщение, как You & 20 Others . Чтобы реализовать это, нам нужно изменить наши sp_GetAllWishes чтобы включить немного кода, указывающего, понравилось ли sp_GetAllWishes в систему пользователю конкретное желание или нет. Чтобы проверить, понравилось ли желание, мы делаем вызов функции. Создайте функцию с именем hasLiked которая принимает ID пользователя и ID желания в качестве параметров и возвращает независимо от того, понравилось ли это пожелание пользователю или нет.

01
02
03
04
05
06
07
08
09
10
11
DELIMITER $$
CREATE DEFINER=`root`@`localhost` FUNCTION `hasLiked`(
    p_wish int,
    p_user int
) RETURNS int(11)
BEGIN
     
    select wish_like into @myval from tbl_likes where wish_id = p_wish and user_id = p_user;
RETURN @myval;
END$$
DELIMITER ;

Теперь вызовите вышеупомянутую функцию MySQL hasLiked внутри sp_GetAllWishes чтобы возвратить дополнительное поле в возвращенном наборе данных, указывающее статус пользователя как.

1
2
3
4
5
6
7
8
9
DELIMITER $$
 
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_GetAllWishes`(
    p_user int
)
BEGIN
    select wish_id,wish_title,wish_description,wish_file_path,getSum(wish_id),hasLiked(wish_id,p_user)
    from tbl_wish where wish_private = 0;
END

Откройте app.py и измените вызов хранимой процедуры MySQL sp_GetAllWishes чтобы включить ID пользователя в качестве параметра.

1
2
3
4
_user = session.get(‘user’)
conn = mysql.connect()
cursor = conn.cursor()
cursor.callproc(‘sp_GetAllWishes’,(_user,))

Теперь измените метод getAllWishes чтобы включить аналогичный статус пользователя для конкретного желания. Измените код, чтобы включить HasLiked в созданный словарь.

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

Внутри JavaScript-функции CreateThumb мы проверим наличие HasLiked и добавим соответствующий HTML- HasLiked .

1
2
3
4
5
if (hasLiked == «1») {
    likeSpan.html(‘&nbsp;You & ‘ + (Number(like) — 1) + ‘ Others’);
} else {
    likeSpan.html(‘&nbsp;’ + like + ‘ like(s)’);
}

Как видно из приведенного выше кода, мы показываем счетчик похожих, если пользователю не понравилось определенное желание. Если пользователю понравилось пожелание, мы показываем более информативное сообщение.

Панель инструментов со статусом лайка

В тот момент, когда мы нажимаем кнопку «Мне нравится», статус «Мне нравится» обновляется в базе данных, но не изменяется в панели управления. Так что давайте обновим его в обратном вызове AJAX при нажатии кнопки «Мне like .

Начнем с внесения изменений в хранимую процедуру MySQL sp_AddUpdateLikes . Ранее мы передавали статус «лайк», 1 для «лайк» и 0 для «нет». Мы изменим это и переключим подобное / отличие в хранимой процедуре. Откройте sp_AddUpdateLikes и выберите подобный статус в переменную и проверьте статус переменной. Если переменная status похожа, мы будем обновлять статус, сравнивая его с наоборот. Вот модифицированная хранимая процедура sp_AddUpdateLikes .

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
— ———————————————————————————
— Routine DDL
— Note: comments before and after the routine body will not be stored by the server
— ———————————————————————————
DELIMITER $$
 
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_AddUpdateLikes`(
    p_wish_id int,
    p_user_id int,
    p_like int
)
BEGIN
     
    if (select exists (select 1 from tbl_likes where wish_id = p_wish_id and user_id = p_user_id)) then
 
         
        select wish_like into @currentVal from tbl_likes where wish_id = p_wish_id and user_id = p_user_id;
         
        if @currentVal = 0 then
            update tbl_likes set wish_like = 1 where wish_id = p_wish_id and user_id = p_user_id;
        else
            update tbl_likes set wish_like = 0 where wish_id = p_wish_id and user_id = p_user_id;
        end if;
         
    else
         
        insert into tbl_likes(
            wish_id,
            user_id,
            wish_like
        )
        values(
            p_wish_id,
            p_user_id,
            p_like
        );
 
 
    end if;
END

В JavaScript-функции CreateThumb назначьте ID для likeSpan который мы создали ранее, чтобы мы могли обновлять статус по мере необходимости.

1
var likeSpan = $(‘<span>’).attr({‘aria-hidden’:’true’,’id’:’span_’+id});

Откройте app.py Внутри метода addUpdateLike , после успешного обновления данных, мы получим желаемое количество и статус, используя другой вызов хранимой процедуры. Поэтому создайте хранимую процедуру MySQL с именем sp_getLikeStatus . Внутри sp_getLikeStatus мы будем вызывать уже созданные функции MySQL getSum и hasLiked для получения статуса.

1
2
3
4
5
6
7
8
9
DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_getLikeStatus`(
    IN p_wish_id int,
    IN p_user_id int
)
BEGIN
    select getSum(p_wish_id),hasLiked(p_wish_id,p_user_id);
END$$
DELIMITER ;

После вызова sp_AddUpdateLikes из метода Python addUpdateLike закройте курсор и соединение.

1
2
3
4
if len(data) is 0:
   conn.commit()
   cursor.close()
   conn.close()

Теперь вызовите хранимую процедуру sp_getLikeStatus .

1
2
3
4
conn = mysql.connect()
cursor = conn.cursor()
cursor.callproc(‘sp_getLikeStatus’,(_wishId,_user))
result = cursor.fetchall()

Возвратите количество и статус лайков вместе с ответом.

1
return json.dumps({‘status’:’OK’,’total’:result[0][0],’likeStatus’:result[0][1]})

В dashboard.html при успешном addUpdateLike вызове вызова AJAX, сделанного методу addUpdateLike , проанализируйте возвращенный ответ и на основе статуса like отобразите счетчик похожих.

01
02
03
04
05
06
07
08
09
10
11
success: function(response) {
 
    var obj = JSON.parse(response);
 
    if (obj.likeStatus == «1») {
        $(‘#span_’ + spId).html(‘&nbsp;You & ‘ + (Number(obj.total) — 1) + ‘ Others’);
    } else {
        $(‘#span_’ + spId).html(‘&nbsp;’ + obj.total + ‘ like(s)’);
    }
   
}

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

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

Дайте нам знать ваши мысли и предложения, или любые исправления, в комментариях ниже. Исходный код из этого урока доступен на GitHub .