Advertisement
  1. Code
  2. Coding Fundamentals
  3. Databases & SQL

Tạo một Ứng dụng Web từ đầu Sử dụng Python Flask và MySQL: Phần 4

Scroll to top
Read Time: 13 min
This post is part of a series called Creating a Web App From Scratch Using Python Flask and MySQL.
Creating a Web App From Scratch Using Python Flask and MySQL: Part 3
Creating a Web App From Scratch Using Python Flask and MySQL: Part 5

() translation by (you can also view the original English article)

Trong phần trước của loạt bài hướng dẫn này, chúng ta đã cài đặt các chức năng cần thiết cho người dùng đã đăng nhập thêm một mong ước. Chúng ta cũng đã tìm hiểu cách hiển thị mong ước được nhập bởi người dùng trên trang chủ của họ.

Trong phần này, chúng ta sẽ cài đặt chức năng chỉnh sửa và xóa những mong ước được nhập bởi người dùng.

Bắt đầu

Hãy bắt đầu bằng cách nhân bản mã nguồn từ phần trước của hướng dẫn trên GitHub.

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

Một khi mã nguồn đã được nhân bản, hãy chuyển đến thư mục dự án và khởi động máy chủ web.

1
cd PythonFlaskMySQLApp_Part3
2
python app.py

Trỏ trình duyệt của bạn đến http://localhost:5002/ và bạn sẽ thấy ứng dụng của bạn đang chạy.

Chỉnh sửa Danh sách Mong ước

Bước 1: Hiển thị Biểu tượng Chỉnh sửa

Chúng ta đã gắn dữ liệu nhận được vào HTML bằng jQuery. Chúng ta sẽ sửa đổi code đó và sử dụng các temlate jQuery để làm cho việc gắn dữ liệu trở nên dễ dàng hơn. Chúng ta cũng sẽ thêm một biểu tượng chỉnh sửa vào HTML để cho phép người dùng cập nhật mong ước. Mở userHome.html và bao gồm một tham chiếu đến các template jQuery.

1
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.js"></script>

Xoá div list-group hiện tại và thay thế bằng code HTML sau:

1
<div class="row">
2
    <div class="col-md-12">
3
4
        <div class="panel-body">
5
6
            <ul id="ulist" class="list-group">
7
8
9
10
            </ul>
11
        </div>
12
13
    </div>
14
</div>

Bên trong UL với list-group, chúng ta sẽ gắn dữ liệu của chúng ta. Định nghĩa listTemplate như sau trong phần body của HTML:

1
<script id="listTemplate" type="text/x-jQuery-tmpl">
2
    <li class="list-group-item">
3
        <div class="checkbox">
4
            <label>
5
                ${Title}
6
            </label>

7
        </div>

8
        <div class="pull-right action-buttons">
9
            <a data-toggle="modal" data-target="#editModal"><span class="glyphicon glyphicon-pencil"></span></a>
10
           
11
        </div>

12
    </li>

13
</script>

Chỉnh sửa callback success của AJAX jQuery để gắn dữ liệu vào listTemplate.

1
<script>
2
    $(function() {
3
        $.ajax({
4
            url: '/getWish',
5
            type: 'GET',
6
            success: function(res) {
7
8
                // Parse the JSON response

9
                var wishObj = JSON.parse(res);
10
                
11
                // Append to the template

12
                $('#listTemplate').tmpl(wishObj).appendTo('#ulist');
13
14
15
            },
16
            error: function(error) {
17
                console.log(error);
18
            }
19
        });
20
    });
21
</script>

Ngoài ra, thêm một số phong cách trong userHome.html:

1
<style>
2
    .trash {
3
        color: rgb(209, 91, 71);
4
    }
5
    .panel-body .checkbox {
6
        display: inline-block;
7
        margin: 0px;
8
    }
9
    .list-group {
10
        margin-bottom: 0px;
11
    }
12
</style>

Lưu tất cả các thay đổi và khởi động lại máy chủ. Trỏ trình duyệt của bạn đến http://localhost:5002 và đăng nhập bằng một địa chỉ email và mật khẩu hợp lệ. Một khi đã đăng nhập, bạn sẽ có thể nhìn thấy những mong ước được tạo bởi người dùng.

User Home with Edit IconUser Home with Edit IconUser Home with Edit Icon

Bước 2: Hiển thị Hộp thoại Chỉnh sửa

Chúng ta sẽ sử dụng Bootstrap để hiển thị hộp thoại nhằm cung cấp giao diện để chỉnh sửa các mong ước. Hãy bao gồm một tham chiếu đến Bootstrap trong userHome.html.

1
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>

Một khi tham chiếu đã được thêm vào, hãy thêm HTML sau vào userHome.html.

1
<div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="editModalLabel" aria-hidden="true">
2
    <div class="modal-dialog">
3
        <div class="modal-content">
4
            <div class="modal-header">
5
                <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span>
6
                </button>
7
                <h4 class="modal-title" id="editModalLabel">Update Wish</h4>
8
            </div>
9
            <div class="modal-body">
10
                <form role="form">
11
                    <div class="form-group">
12
                        <label for="recipient-name" class="control-label">Title:</label>
13
                        <input type="text" class="form-control" id="editTitle">
14
                    </div>
15
                    <div class="form-group">
16
                        <label for="message-text" class="control-label">Description:</label>
17
                        <textarea class="form-control" id="editDescription"></textarea>
18
                    </div>
19
                </form>
20
            </div>
21
            <div class="modal-footer">
22
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
23
                <button type="button" id="btnUpdate" class="btn btn-primary">Update</button>
24
            </div>
25
        </div>
26
    </div>
27
</div>

HTML ở trên sẽ đóng vai trò như là hộp thoại. Khi người dùng nhấp vào biểu tượng chỉnh sửa, hộp thoại sẽ bật lên. Chúng ta đã thêm thuộc tính data-targetdata-toggle để kích hoạt hộp thoại.

1
 <a data-toggle="modal" data-target="#editModal"><span class="glyphicon glyphicon-pencil"></span></a>

Lưu các thay đổi ở trên và khởi động lại ứng dụng. Sau khi đã đăng nhập vào ứng dụng, hãy nhấp vào biểu tượng chỉnh sửa và bạn sẽ có thể thấy hộp thoại.

Edit Wish PopupEdit Wish PopupEdit Wish Popup

Bước 3: Điền vào Hộp thoại Chỉnh sửa

Khi người dùng nhấp vào biểu tượng chỉnh sửa, chúng ta sẽ hiển thị hộp thoại cập nhật với titledescription. Để bắt đầu, trước tiên chúng ta cần ID của mong ước để lấy các chi tiết của mong ước cụ thể khi người dùng nhấp vào biểu tượng chỉnh sửa. Vì vậy, hãy chỉnh sửa code template jQuery để bao gồm một thuộc tính data-id bổ sung trên phần tử liên kết chỉnh sửa.

1
<a data-id=${Id} onclick="Edit(this)" ><span class="glyphicon glyphicon-pencil"></span></a>

Chúng ta cũng ràng buộc một sự kiện onclick để gọi phương thức Edit. Bên trong hàm Edit, chúng ta sẽ làm cho AJAX gọi đến một phương thức python có tên là getWishById và sẽ trả về các chi tiết của mong ước.

1
function Edit(elm) {
2
    $.ajax({
3
        url: '/getWishById',
4
        data: {
5
            id: $(elm).attr('data-id')
6
        },
7
        type: 'POST',
8
        success: function(res) {
9
            console.log(res);
10
        },
11
        error: function(error) {
12
            console.log(error);
13
        }
14
    });
15
}

Tiếp theo, mở app.py và tạo ra một phương thức gọi là getWishById. Sử dụng phương thức này, chúng ta sẽ lấy được các chi tiết của mong ước cụ thể từ cơ sở dữ liệu.

1
@app.route('/getWishById',methods=['POST'])
2
def getWishById():
3
    try:
4
        if session.get('user'):
5
6
            _id = request.form['id']
7
            _user = session.get('user')
8
9
            conn = mysql.connect()
10
            cursor = conn.cursor()
11
            cursor.callproc('sp_GetWishById',(_id,_user))
12
            result = cursor.fetchall()
13
14
            wish = []
15
            wish.append({'Id':result[0][0],'Title':result[0][1],'Description':result[0][2]})
16
17
            return json.dumps(wish)
18
        else:
19
            return render_template('error.html', error = 'Unauthorized Access')
20
    except Exception as e:
21
        return render_template('error.html',error = str(e))

Như bạn có thể thấy trong phương thức ở trên, chúng ta đã truyền ID của mong ước vào phương thức này và nó sẽ lấy dữ liệu từ cơ sở dữ liệu bằng ID của người dùng và ID của mong ước. Một khi đã lấy được dữ liệu, nó sẽ chuyển đổi dữ liệu đó thành một danh sách và sau đó trả về nó như là dữ liệu JSON.

Tiếp theo, hãy tạo ra thủ tục lưu trữ trong MySQL cần thiết để lấy dữ liệu từ cơ sở dữ liệu.

1
DELIMITER $$
2
3
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_GetWishById`(
4
IN p_wish_id bigint,
5
In p_user_id bigint
6
)
7
BEGIN
8
select * from tbl_wish where wish_id = p_wish_id and wish_user_id = p_user_id;
9
END

Code được hiển thị ở trên là thủ tục lưu trữ để lấy các chi tiết của mong ước cụ thể sử dụng ID của mong ước và ID của người dùng.

Lưu các thay đổi và khởi động lại máy chủ. Sau khi đã đăng nhập vào ứng dụng, nhấp vào biểu tượng chỉnh sửa và bạn sẽ thấy các thông tin được log trong giao diện console của trình duyệt.

Để gắn dữ liệu đã nhận vào hộp thoại HTML, trước tiên hãy xóa thuộc tính data-target và thuộc tính data-toggle khỏi thẻ liên kết chỉnh sửa. Sau đó, thêm code sau vào hàm Edit trong JavaScript để điền vào hộp thoại và bật nó lên.

1
// Parse the received JSON string

2
var data = JSON.parse(res);
3
4
//Populate the Pop up

5
$('#editTitle').val(data[0]['Title']);
6
$('#editDescription').val(data[0]['Description']);
7
8
// Trigger the Pop Up

9
$('#editModal').modal();

Lưu các thay đổi và khởi động lại máy chủ. Một khi đã đăng nhập vào ứng dụng, hãy thử nhấp vào biểu tượng chỉnh sửa và bạn sẽ thấy cửa sổ bật lên với title và description.

Populated Edit Pop UpPopulated Edit Pop UpPopulated Edit Pop Up

Bước 4: Cập nhật các Chi tiết của Mong ước

Để cài đặt tính năng cập nhật, hãy tạo một thủ tục lưu trữ trong MySQL.

1
DELIMITER $$
2
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_updateWish`(
3
IN p_title varchar(45),
4
IN p_description varchar(1000),
5
IN p_wish_id bigint,
6
In p_user_id bigint
7
)
8
BEGIN
9
update tbl_wish set wish_title = p_title,wish_description = p_description
10
    where wish_id = p_wish_id and wish_user_id = p_user_id;
11
END$$
12
DELIMITER ;

Như đã thấy trong thủ tục được lưu trữ ở trên, chúng ta sẽ truyền vào titledescription đã chỉnh sửa cùng với ID của mong ước và người dùng để cập nhật các chi tiết trong cơ sở dữ liệu.

Tiếp theo, hãy tạo ra một phương thức mới được gọi là updateWish để cập nhật các chi tiết. Dưới đây là phương thức updateWish:

1
@app.route('/updateWish', methods=['POST'])
2
def updateWish():
3
    try:
4
        if session.get('user'):
5
            _user = session.get('user')
6
            _title = request.form['title']
7
            _description = request.form['description']
8
            _wish_id = request.form['id']
9
10
11
12
            conn = mysql.connect()
13
            cursor = conn.cursor()
14
            cursor.callproc('sp_updateWish',(_title,_description,_wish_id,_user))
15
            data = cursor.fetchall()
16
17
            if len(data) is 0:
18
                conn.commit()
19
                return json.dumps({'status':'OK'})
20
            else:
21
                return json.dumps({'status':'ERROR'})
22
    except Exception as e:
23
        return json.dumps({'status':'Unauthorized access'})
24
    finally:
25
        cursor.close()
26
        conn.close()

Như đã thấy trong đoạn code ở trên, sau khi xác nhận một session hợp lệ, chúng ta đã thu thập dữ liệu được post và gọi thủ tục lưu trữ sp_updateWish để cập nhật các chi tiết.

Để gọi phương thức updateWish, chúng ta cần phải đính kèm một sự kiện click trên button Update. Vì vậy, hãy đặt tên cho button Update là btnUpdate và gắn vào một sự kiện onclick như sau:

1
$('#btnUpdate').click(function() {
2
    $.ajax({
3
        url: '/updateWish',
4
        data: {
5
            title: $('#editTitle').val(),
6
            description: $('#editDescription').val(),
7
            id: localStorage.getItem('editId')
8
        },
9
        type: 'POST',
10
        success: function(res) {
11
            $('#editModal').modal('hide');
12
            // Re populate the grid

13
        },
14
        error: function(error) {
15
            console.log(error);
16
        }
17
    })
18
});

Như đã thấy trong đoạn code ở trên, chúng ta lấy editId từ localStorage, vì vậy, bên trong hàm Edit lưu ID vào localStorage.

1
localStorage.setItem('editId',$(elm).attr('data-id'));

Gom việc gọi getWish trong AJAX thành một hàm, từ đó chúng ta có thể gọi nó một lần nữa khi dữ liệu đã được cập nhật.

1
function GetWishes() {
2
    $.ajax({
3
        url: '/getWish',
4
        type: 'GET',
5
        success: function(res) {
6
            var wishObj = JSON.parse(res);
7
            $('#ulist').empty();
8
            $('#listTemplate').tmpl(wishObj).appendTo('#ulist');
9
        },
10
        error: function(error) {
11
            console.log(error);
12
        }
13
    });
14
}

Gọi hàm getWishes trong callback success của update trong AJAX.

1
$('#btnUpdate').click(function() {
2
    $.ajax({
3
        url: '/updateWish',
4
        data: {
5
            title: $('#editTitle').val(),
6
            description: $('#editDescription').val(),
7
            id: localStorage.getItem('editId')
8
        },
9
        type: 'POST',
10
        success: function(res) {
11
            $('#editModal').modal('hide');
12
            
13
            // Re populate the grid

14
            GetWishes();
15
        },
16
        error: function(error) {
17
            console.log(error);
18
        }
19
    })
20
});

Lưu tất cả các thay đổi và khởi động lại máy chủ. Một khi đã đăng nhập vào ứng dụng, hãy thử chỉnh sửa các mong ước có sẵn do người dùng tạo.

Xóa một Mong ước

Bước 1: Hiển thị Hộp thoại Xác nhận

Thêm code HTML sau đây vào userHome.html.

1
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="deleteModalLabel" aria-hidden="true">
2
    <div class="modal-dialog">
3
        <div class="modal-content">
4
            <div class="modal-header" style="text-align:center;">
5
                <h4 class="modal-title" style="color:red;" id="deleteModalLabel">You are going to Delete this forever !!</h4>
6
            </div>
7
8
            <div class="modal-footer">
9
                <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
10
                <button type="button" class="btn btn-primary">Delete</button>
11
            </div>
12
        </div>
13
    </div>
14
</div>

Thêm biểu tượng xóa bên trong listTemplate bằng cách thêm code HTML sau:

1
<a data-id=${Id} onclick="ConfirmDelete(this)" ><span class="glyphicon glyphicon-trash"></span></a>

Khi nhấp vào biểu tượng xóa ở trên, chúng ta sẽ gọi hàm JavaScript có tên là confirmDelete nơi chúng ta sẽ kích hoạt cửa sổ hộp thoại xác nhận.

1
function ConfirmDelete(elem) {
2
    localStorage.setItem('deleteId', $(elem).attr('data-id'));
3
    $('#deleteModal').modal();
4
}

Lưu các thay đổi và khởi động lại máy chủ. Một khi đã đăng nhập, hãy nhấp vào biểu tượng xóa trong danh sách mong ước và bạn sẽ có thể thấy hộp thoại xác nhận bật lên.

Delete Confirmation PopupDelete Confirmation PopupDelete Confirmation Popup

Bước 2: Xóa một Mong ước

Để cài đặt tính năng Xóa mong ước, trước tiên chúng ta hãy tạo ra thủ tục lưu trữ MySQL.

1
DELIMITER $$
2
USE `BucketList`$$
3
CREATE PROCEDURE `sp_deleteWish` (
4
IN p_wish_id bigint,
5
IN p_user_id bigint
6
)
7
BEGIN
8
delete from tbl_wish where wish_id = p_wish_id and wish_user_id = p_user_id;
9
END$$
10
11
DELIMITER ;

Thủ tục ở trên nhận ID của mong ước và ID của người dùng và xóa mong ước tương ứng khỏi cơ sở dữ liệu.

Tiếp theo, hãy tạo ra một phương thức bên trong app.py để gọi thủ tục sp_deleteWish.

Chúng ta sẽ tạo ra một phương thức gọi là deleteWish để xóa mong ước.

1
@app.route('/deleteWish',methods=['POST'])
2
def deleteWish():
3
    try:
4
        if session.get('user'):
5
            _id = request.form['id']
6
            _user = session.get('user')
7
8
            conn = mysql.connect()
9
            cursor = conn.cursor()
10
            cursor.callproc('sp_deleteWish',(_id,_user))
11
            result = cursor.fetchall()
12
13
            if len(result) is 0:
14
                conn.commit()
15
                return json.dumps({'status':'OK'})
16
            else:
17
                return json.dumps({'status':'An Error occured'})
18
        else:
19
            return render_template('error.html',error = 'Unauthorized Access')
20
    except Exception as e:
21
        return json.dumps({'status':str(e)})
22
    finally:
23
        cursor.close()
24
        conn.close()

Trong phương thức ở trên, chúng ta trước tiên xác minh session. Một khi chúng ta đã xác minh session user, sử dụng ID của mong ước và ID của người dùng, chúng ta gọi thủ tục lưu trữ sp_deleteWish.

Để gọi phương thức deleteWish ở trên, hãy thêm một sự kiện onclick vào button Delete trong cửa sổ hộp thoại xác nhận.

1
<button type="button" class="btn btn-primary" onclick="Delete()">Delete</button>

Tạo một hàm JavaScript được gọi là Delete, và bên trong Delete làm cho AJAX gọi phương thức deleteWish của python.

1
function Delete() {
2
    $.ajax({
3
        url: '/deleteWish',
4
        data: {
5
            id: localStorage.getItem('deleteId')
6
        },
7
        type: 'POST',
8
        success: function(res) {
9
            var result = JSON.parse(res);
10
            if (result.status == 'OK') {
11
                $('#deleteModal').modal('hide');
12
                GetWishes();
13
            } else {
14
                alert(result.status);
15
            }
16
        },
17
        error: function(error) {
18
            console.log(error);
19
        }
20
    });
21
}

Trong hàm callback success của hàm Delete ở trên, chúng ta sẽ kiểm tra trạng thái trả về và nếu OK, chúng ta sẽ ẩn hộp thoại và tải lại các mong ước.

Lưu các thay đổi và khởi động lại máy chủ. Một khi đăng nhập vào ứng dụng, hãy thử xóa một mong ước khỏi trang chủ của người dùng.

Phần tóm tắt

Trong phần này, chúng ta đã tìm hiểu cách cài đặt chức năng Chỉnh sửaXoá mong ước cho Ứng dụng Danh sách Mong ước của chúng ta. Trong phần tiếp theo của loạt bài này, chúng ta sẽ cài đặt phân trang cho danh sách trên trang chủ của người dùng và đồng thời cài đặt thêm một vài tính năng nữa.

Mã nguồn từ hướng dẫn này có sẵn trên GitHub.

Hãy cho chúng tôi biết những suy nghĩ của bạn trong phần bình luận ​​dưới đây nhé!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.