Vietnamese (Tiếng Việt) translation by Dai Phong (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 chức năng đăng nhập và đăng xuất cho ứng dụng Danh sách Mong ước của chúng ta. Trong phần này, chúng ta sẽ cài đặt back-end và front-end cần thiết để cho người dùng thêm và hiển thị các phần tử trong danh sách.
Bắt đầu
Hãy bắt đầu bằng cách nhân bản mã nguồn trước đó cho hướng dẫn từ GitHub.
1 |
git clone https://github.com/jay3dec/PythonFlaskMySQLApp_Part2.git |
Khi mã nguồn đã được nhân bản, điều hướng đến thư mục dự án và khởi động máy chủ web.
1 |
cd PythonFlaskMySQLApp_Part2
|
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 đang chạy.



Thêm Phần tử vào Danh sách
Bước 1: Tạo một Giao diện để Thêm Phần tử
Chúng ta sẽ bắt đầu bằng cách tạo giao diện để cho người dùng đã đăng nhập thêm các phần tử trong danh sách. Điều hướng đến thư mục templates
bên trong thư mục dự án và tạo tập tin có tên addWish.html
. Mở addWish.html
và thêm code HTML sau:
1 |
<!DOCTYPE html>
|
2 |
<html lang="en"> |
3 |
|
4 |
<head>
|
5 |
<title>Python Flask Bucket List App</title> |
6 |
|
7 |
|
8 |
<link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet"> |
9 |
|
10 |
<link href="http://getbootstrap.com/examples/jumbotron-narrow/jumbotron-narrow.css" rel="stylesheet"> |
11 |
|
12 |
<script src="../static/js/jquery-1.11.2.js"></script> |
13 |
|
14 |
|
15 |
</head>
|
16 |
|
17 |
<body>
|
18 |
|
19 |
<div class="container"> |
20 |
<div class="header"> |
21 |
<nav>
|
22 |
<ul class="nav nav-pills pull-right"> |
23 |
<li role="presentation" class="active"><a href="#">Add Item</a> |
24 |
</li>
|
25 |
<li role="presentation"><a href="/logout">Logout</a> |
26 |
</li>
|
27 |
</ul>
|
28 |
</nav>
|
29 |
<h3 class="text-muted">Python Flask App</h3> |
30 |
</div>
|
31 |
<section>
|
32 |
<form class="form-horizontal" method="post" action="/addWish"> |
33 |
<fieldset>
|
34 |
|
35 |
<!-- Form Name -->
|
36 |
<legend>Create Your Wish</legend> |
37 |
|
38 |
<!-- Text input-->
|
39 |
<div class="form-group"> |
40 |
<label class="col-md-4 control-label" for="txtTitle">Title</label> |
41 |
<div class="col-md-4"> |
42 |
<input id="txtTitle" name="inputTitle" type="text" placeholder="placeholder" class="form-control input-md"> |
43 |
</div>
|
44 |
</div>
|
45 |
|
46 |
<!-- Textarea -->
|
47 |
<div class="form-group"> |
48 |
<label class="col-md-4 control-label" for="txtPost">Post</label> |
49 |
<div class="col-md-4"> |
50 |
<textarea class="form-control" id="txtPost" name="inputDescription"></textarea> |
51 |
</div>
|
52 |
</div>
|
53 |
|
54 |
<!-- Button -->
|
55 |
<div class="form-group"> |
56 |
<label class="col-md-4 control-label" for="singlebutton"></label> |
57 |
<div class="col-md-4"> |
58 |
<input id="singlebutton" name="singlebutton" class="btn btn-primary" type="submit" value="Publish" /> |
59 |
</div>
|
60 |
</div>
|
61 |
|
62 |
</fieldset>
|
63 |
</form>
|
64 |
|
65 |
</section>
|
66 |
<footer class="footer"> |
67 |
<p>© Company 2015</p> |
68 |
</footer>
|
69 |
|
70 |
</div>
|
71 |
</body>
|
72 |
|
73 |
</html>
|
Mở app.py
và thêm một tuyến và phương thức mới để hiển thị trang Add Wish
.
1 |
@app.route('/showAddWish') |
2 |
def showAddWish(): |
3 |
return render_template('addWish.html') |
Mở userHome.html
và thêm một phần tử menu mới để liên kết đến trang Add Wish
.
1 |
<li role="presentation"><a href="/showAddWish">Add Wish</a></li> |
Lưu 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 địa chỉ email và mật khẩu hợp lệ. Sau khi đăng nhập, nhấp chuột vào liên kết Add Wish và bạn sẽ thấy trang Add Wish.



Bước 2: Cài đặt Cơ sở dữ liệu
Để thêm các phần tử vào danh sách, chúng ta cần tạo một bảng có tên là tbl_wish
.
1 |
CREATE TABLE `tbl_wish` ( |
2 |
`wish_id` int(11) NOT NULL AUTO_INCREMENT, |
3 |
`wish_title` varchar(45) DEFAULT NULL, |
4 |
`wish_description` varchar(5000) DEFAULT NULL, |
5 |
`wish_user_id` int(11) DEFAULT NULL, |
6 |
`wish_date` datetime DEFAULT NULL, |
7 |
PRIMARY KEY (`wish_id`) |
8 |
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1; |
tbl_wish
sẽ có title
, description
và ID
của người dùng đã tạo ra mong ước.
Tiếp theo, chúng ta cần phải tạo một thủ tục lưu trữ MySQL để thêm các phần tử vào bảng tbl_wish
.
1 |
USE `BucketList`; |
2 |
DROP procedure IF EXISTS `BucketList`.`sp_addWish`; |
3 |
|
4 |
DELIMITER $$ |
5 |
USE `BucketList`$$ |
6 |
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_addWish`( |
7 |
IN p_title varchar(45), |
8 |
IN p_description varchar(1000), |
9 |
IN p_user_id bigint |
10 |
)
|
11 |
BEGIN
|
12 |
insert into tbl_wish( |
13 |
wish_title, |
14 |
wish_description, |
15 |
wish_user_id, |
16 |
wish_date
|
17 |
)
|
18 |
values
|
19 |
(
|
20 |
p_title, |
21 |
p_description, |
22 |
p_user_id, |
23 |
NOW() |
24 |
);
|
25 |
END$$ |
26 |
|
27 |
DELIMITER ; |
28 |
;
|
Bước 3: Tạo một Phương thức Python để gọi Thủ tục Lưu trữ MySQL
Hãy tạo một phương thức gọi là addWish
trong app.py
.
1 |
@app.route('/addWish',methods=['POST']) |
2 |
def addWish(): |
3 |
# Code will be here
|
Vì chúng ta sẽ post dữ liệu lên phương thức này, nên chúng ta định nghĩa nó một cách rõ ràng trong tuyến (route) đã định nghĩa.
Khi gọi phương thức addWish
, chúng ta cần xác minh nó có hợp lệ hay không bằng cách kiểm tra biến session user
có tồn tại hay không. Một khi chúng ta đã xác minh session, chúng ta sẽ đọc title
và description
được post lên.
1 |
_title = request.form['inputTitle'] |
2 |
_description = request.form['inputDescription'] |
3 |
_user = session.get('user') |
Một khi chúng ta có các giá trị input cần thiết, chúng ta sẽ mở một kết nối MySQL và gọi thủ tục lưu trữ sp_addWish
.
1 |
conn = mysql.connect() |
2 |
cursor = conn.cursor() |
3 |
cursor.callproc('sp_addWish',(_title,_description,_user)) |
4 |
data = cursor.fetchall() |
Sau khi chúng ta đã thực thi thủ tục lưu trữ, chúng ta cần phải commit những thay đổi vào cơ sở dữ liệu.
1 |
if len(data) is 0: |
2 |
conn.commit() |
3 |
return redirect('/userHome') |
4 |
else: |
5 |
return render_template('error.html',error = 'An error occurred!') |
Dưới đây là phương thức addWish
hoàn chỉnh.
1 |
@app.route('/addWish',methods=['POST']) |
2 |
def addWish(): |
3 |
try: |
4 |
if session.get('user'): |
5 |
_title = request.form['inputTitle'] |
6 |
_description = request.form['inputDescription'] |
7 |
_user = session.get('user') |
8 |
|
9 |
conn = mysql.connect() |
10 |
cursor = conn.cursor() |
11 |
cursor.callproc('sp_addWish',(_title,_description,_user)) |
12 |
data = cursor.fetchall() |
13 |
|
14 |
if len(data) is 0: |
15 |
conn.commit() |
16 |
return redirect('/userHome') |
17 |
else: |
18 |
return render_template('error.html',error = 'An error occurred!') |
19 |
|
20 |
else: |
21 |
return render_template('error.html',error = 'Unauthorized Access') |
22 |
except Exception as e: |
23 |
return render_template('error.html',error = str(e)) |
24 |
finally: |
25 |
cursor.close() |
26 |
conn.close() |
Lưu tất cả mã nguồn và khởi động lại máy chủ. Trỏ trình duyệt đến http://localhost:5002 và đăng nhập bằng địa chỉ email và mật khẩu hợp lệ. Khi đã đăng nhập, hãy nhấp vào liên kết Add Wish. Nhập title
và description
cho mong ước của bạn và nhấp vào Publish. Khi thêm thành công mong ước, nó sẽ chuyển hướng đến trang chủ của người dùng. Đăng nhập vào cơ sở dữ liệu MySQL và mong ước của bạn sẽ được lưu trong bảng tbl_wish
.
Hiển thị một Phần tử trong Danh sách Mong ước
Bước 1: Tạo một Thủ tục Lưu trữ để lấy một Mong ước
Hãy tạo ra một thủ tục lưu trữ MySQL sẽ lấy những mong ước được tạo ra bởi người dùng. Nó sẽ nhận ID
của người dùng như một tham số và trả về một tập hợp các mong ước được tạo bởi người dùng có ID đó.
1 |
USE `BucketList`; |
2 |
DROP procedure IF EXISTS `sp_GetWishByUser`; |
3 |
|
4 |
DELIMITER $$ |
5 |
USE `BucketList`$$ |
6 |
CREATE PROCEDURE `sp_GetWishByUser` ( |
7 |
IN p_user_id bigint |
8 |
)
|
9 |
BEGIN
|
10 |
select * from tbl_wish where wish_user_id = p_user_id; |
11 |
END$$ |
12 |
|
13 |
DELIMITER ; |
14 |
Bước 2: Tạo một Phương thức Python để Truy vấn Dữ liệu
Tiếp theo, hãy tạo ra một phương thức Python sẽ gọi thủ tục lưu trữ sp_GetWishByUser
để lấy những mong ước được tạo ra bởi người dùng. Thêm một phương thức được gọi là getWish
trong app.py
.
1 |
@app.route('/getWish') |
2 |
def getWish(): |
3 |
try: |
4 |
if session.get('user'): |
5 |
_user = session.get('user') |
6 |
else: |
7 |
return render_template('error.html', error = 'Unauthorized Access') |
8 |
except Exception as e: |
9 |
return render_template('error.html', error = str(e)) |
Như đã thấy trong đoạn code ở trên, phương thức này chỉ có thể được gọi với session user
hợp lệ. Một khi chúng ta đã xác nhận một session user hợp lệ, chúng ta sẽ tạo một kết nối đến cơ sở dữ liệu MySQL và gọi thủ tục lưu trữ sp_GetWishByUser
.
1 |
_user = session.get('user') |
2 |
|
3 |
# Connect to MySQL and fetch data
|
4 |
con = mysql.connect() |
5 |
cursor = con.cursor() |
6 |
cursor.callproc('sp_GetWishByUser',(_user,)) |
7 |
wishes = cursor.fetchall() |
Một khi chúng ta lấy được dữ liệu từ MySQL, chúng ta sẽ phân tích dữ liệu và chuyển đổi nó thành một dictionary
sao cho nó dễ dàng trả về JSON
.
1 |
wishes_dict = [] |
2 |
for wish in wishes: |
3 |
wish_dict = { |
4 |
'Id': wish[0], |
5 |
'Title': wish[1], |
6 |
'Description': wish[2], |
7 |
'Date': wish[4]} |
8 |
wishes_dict.append(wish_dict) |
Sau khi chuyển đổi dữ liệu thành dictionary
, chúng ta sẽ chuyển dữ liệu sang JSON
và trả dữ liệu về.
1 |
return json.dumps(wishes_dict) |
Dưới đây là phương thức getWish
đầy đủ.
1 |
@app.route('/getWish') |
2 |
def getWish(): |
3 |
try: |
4 |
if session.get('user'): |
5 |
_user = session.get('user') |
6 |
|
7 |
con = mysql.connect() |
8 |
cursor = con.cursor() |
9 |
cursor.callproc('sp_GetWishByUser',(_user,)) |
10 |
wishes = cursor.fetchall() |
11 |
|
12 |
wishes_dict = [] |
13 |
for wish in wishes: |
14 |
wish_dict = { |
15 |
'Id': wish[0], |
16 |
'Title': wish[1], |
17 |
'Description': wish[2], |
18 |
'Date': wish[4]} |
19 |
wishes_dict.append(wish_dict) |
20 |
|
21 |
return json.dumps(wishes_dict) |
22 |
else: |
23 |
return render_template('error.html', error = 'Unauthorized Access') |
24 |
except Exception as e: |
25 |
return render_template('error.html', error = str(e)) |
Bước 3: Gắn dữ liệu JSON vào HTML
Khi trang chủ của người dùng được nạp, chúng ta sẽ gọi phương thức getWish
bằng AJAX của jQuery và gắn dữ liệu đã nhận vào HTML của chúng ta. Trong userHome.html
thêm script AJAX bằng jQuery
sau đây:
1 |
<script>
|
2 |
$(function() { |
3 |
$.ajax({ |
4 |
url: '/getWish', |
5 |
type: 'GET', |
6 |
success: function(res) { |
7 |
console.log(res); |
8 |
},
|
9 |
error: function(error) { |
10 |
console.log(error); |
11 |
}
|
12 |
});
|
13 |
});
|
14 |
</script>
|
Lưu các thay đổi ở trên và khởi động lại máy chủ. Một khi đã đăng nhập bằng địa chỉ email và mật khẩu hợp lệ, hãy kiểm tra giao diện console trong trình duyệt của bạn và bạn sẽ có danh sách mong ước lấy được từ cơ sở dữ liệu như sau:
1 |
[{
|
2 |
"Date": "Fri, 23 Jan 2015 23:26:05 GMT", |
3 |
"Description": "I want to climb Mount Everest", |
4 |
"Id": 1, |
5 |
"Title": "Climb Everest" |
6 |
}, { |
7 |
"Date": "Fri, 23 Jan 2015 23:27:05 GMT", |
8 |
"Description": "I want to jump from top of a mountain", |
9 |
"Id": 2, |
10 |
"Title": "Bungee Jump" |
11 |
}]
|
Bây giờ, chúng ta cần lặp qua dữ liệu JSON
và gắn nó vào HTML. Chúng ta sẽ sử dụng list-group
của bootstrap để hiển thị các phần tử trong danh sách mong ước của chúng ta. Dưới đây là template list-group
cơ bản:
1 |
<div class="list-group"> |
2 |
<a href="#" class="list-group-item active"> |
3 |
<h4 class="list-group-item-heading">Wish Title</h4> |
4 |
<p class="list-group-item-text">Wish Description</p> |
5 |
</a>
|
6 |
</div>
|
Thêm code HTML ở trên vào div jumbotron
trong userHome.html
. Nó sẽ trông giống như sau:



Bây giờ, những gì chúng ta sẽ làm là tạo nhóm div list-group
như ở trên cho mỗi mong ước trong danh sách và thêm nó vào div jumbotron
. Bên trong callback success của hàm getWish
, tạo một div như sau:
1 |
var div = $('<div>') |
2 |
.attr('class', 'list-group') |
3 |
.append($('<a>') |
4 |
.attr('class', 'list-group-item active') |
5 |
.append($('<h4>') |
6 |
.attr('class', 'list-group-item-heading'), |
7 |
$('<p>') |
8 |
.attr('class', 'list-group-item-text'))); |
Chúng ta sẽ nhân bản div ở trên để tạo div list-group
cho mỗi phần tử mong ước. Tiếp theo, phân tích cú pháp JSON
trả về thành một đối tượng JavaScript.
1 |
var wishObj = JSON.parse(res); |
Bây giờ, lặp qua wishObj
và đối với mỗi phần tử mong ước, nhân bản một div mới và thêm nó vào div jumbotron
.
1 |
var wish = ''; |
2 |
|
3 |
$.each(wishObj, function(index, value) { |
4 |
wish = $(div).clone(); |
5 |
$(wish).find('h4').text(value.Title); |
6 |
$(wish).find('p').text(value.Description); |
7 |
$('.jumbotron').append(wish); |
8 |
});
|
Lưu các thay đổi ở trên và khởi động lại máy chủ. Đăng nhập bằng địa chỉ email và mật khẩu hợp lệ và bạn sẽ có thể xem danh sách mong ước được tạo bởi người dùng cụ thể.



Phần tóm tắt
Trong hướng dẫn này, chúng ta đã cài đặt một giao diện cho người dùng đã đăng nhập để tạo ra một mong ước. Chúng ta cũng đã cài đặt các phương thức cần thiết và thủ tục lưu trữ trong cơ sở dữ liệu để lấy và hiển thị các mong ước được tạo ra lên trên trang chủ của người dùng.
Trong phần tiếp theo của loạt bài này, chúng tôi sẽ giới thiệu cách cài đặt chức năng Chỉnh sửa
và Xoá
cho danh sách mong ước được hiển thị trong trang chủ của người dùng.
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é!