() translation by (you can also view the original English article)
이 연재 기사의 2부에서는 버킷 리스트 애플리케이션의 로그인 및 로그아웃 기능을 구현했습니다. 3부에서는 사용자가 버킷 리스트 항목을 추가하고 표시하는 데 필요한 백엔드와 프런트엔드를 구현하겠습니다..
시작하기
먼저 깃허브(GitHub)에서 튜토리얼의 이전 내용을 복제합니다.
1 |
git clone https://github.com/jay3dec/PythonFlaskMySQLApp_Part2.git |
소스코드가 복제되면 프로젝트 디렉터리로 이동해서 웹 서버를 구동합니다.
1 |
cd PythonFlaskMySQLApp_Part2
|
2 |
python app.py |
브라우저에서 http://localhost:5002/로 이동하면 실행 중인 애플리케이션을 볼 수 있을 것입니다.



버킷 리스트 항목 추가
1단계: 항목 추가 인터페이스 만들기
로그인한 사용자가 버킷 리스트 항목을 추가하는 인터페이스를 만드는 것으로 시작하겠습니다. 프로젝트 디렉터리 내의 templates
폴더로 이동한 후 addWish.html
이라는 파일을 만듭니다. addWish.html
을 열고 다음 HTML 코드를 추가합니다.
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>
|
app.py
를 열고 Add Wish
페이지를 표시하는 새로운 라우트와 메서드를 추가합니다.
1 |
@app.route('/showAddWish') |
2 |
def showAddWish(): |
3 |
return render_template('addWish.html') |
userHome.html
을 열고 Add Wish
페이지로 연결되는 새 메뉴 항목을 추가합니다.
1 |
<li role="presentation"><a href="/showAddWish">Add Wish</a></li> |
변경 사항을 저장하고 서버를 다시 시작합니다. 브라우저에서 http://localhost:5002로 이동한 후 유효한 이메일 주소와 비밀번호를 사용해 로그인합니다. 로그인한 후 Add Wish 링크를 클릭하면 Add Wish 페이지가 표시됩니다.



2단계: 데이터베이스 구현
버킷 리스트에 항목을 추가하려면 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
테이블에는 title
, description
, 그리고 희망사항을 작성한 사용자의 ID
를 담을 것입니다.
다음으로 tbl_wish
테이블에 항목을 추가하는 MySQL 저장 프로시저를 생성해야 합니다.
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 |
;
|
3단계: MySQL 저장 프로시저를 호출하는 파이썬 메서드 작성
app.py
에 addWish
라는 메서드를 만듭니다.
1 |
@app.route('/addWish',methods=['POST']) |
2 |
def addWish(): |
3 |
# Code will be here
|
이 메서드로 데이터를 전송할 것이므로 정의한 라우트에 명시적으로 선언했습니다.
addWish
메서드가 호출될 때 세션 변수인 user
가 존재하는지 확인해서 실제 호출인지 확인해야 합니다. 세션을 확인하고 나면 전송된 title
과 description
을 읽습니다.
1 |
_title = request.form['inputTitle'] |
2 |
_description = request.form['inputDescription'] |
3 |
_user = session.get('user') |
필요한 입력값을 얻으면 MySQL 연결을 열고 sp_addWish
저장 프로시저를 호출합니다.
1 |
conn = mysql.connect() |
2 |
cursor = conn.cursor() |
3 |
cursor.callproc('sp_addWish',(_title,_description,_user)) |
4 |
data = cursor.fetchall() |
저장 프로시저를 실행한 후에는 데이터베이스에 변경 사항을 커밋해야 합니다.
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!') |
다음은 addWish
메서드의 전체 코드입니다.
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() |
모든 소스코드를 저장하고 서버를 다시 시작합니다. 브라우저에서 http://localhost:5002로 이동한 후 유효한 이메일 주소와 비밀번호를 사용해 로그인합니다. 로그인한 후 Add Wish 링크를 클릭합니다. 희망사항의 title
과 description
을 입력하고 Publish를 클릭합니다. 희망사항이 성공적으로 추가되면 사용자 홈 페이지로 리디렉션될 것입니다. MySQL 데이터베이스에 로그인해서 보면 tbl_wish
테이블에 희망사항이 들어있을 것입니다.
버킷 리스트 항목 보여주기
1단계: 희망사항을 조회하는 저장 프로시저 작성
사용자가 만든 희망사항을 가져오는 MySQL 저장 프로시저를 만들어 봅시다. 이 프로시저에서는 사용자 ID
를 매개변수로 받아 특정 사용자 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 |
2단계: 데이터를 조회하기 위한 파이썬 메서드 작성
다음으로, 사용자가 만든 희망사항을 가져오는 sp_GetWishByUser
저장 프로시저를 호출하는 파이썬 메서드를 작성해 봅시다. app.py
에 getWish
라는 메서드를 추가합니다.
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)) |
위의 코드에서 볼 수 있듯이 이 메서드는 유효한 user
세션에서만 호출될 수 있습니다. 유효한 사용자 세션을 검사하고 나면 MySQL 데이터베이스에 대한 연결을 생성하고 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() |
MySQL에서 데이터를 가져오면 JSON
으로 반환하기 쉽게 데이터를 파싱해서 dictionary
로 변환합니다.
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) |
데이터를 dictionary
로 변환하고 나면 해당 데이터를 JSON
으로 변환한 후 반환합니다.
1 |
return json.dumps(wishes_dict) |
다음은 getWish
메서드의 전체 코드입니다.
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)) |
3단계: JSON 데이터를 HTML에 바인딩
사용자 홈 페이지가 로드되면 jQuery AJAX를 이용해 getWish
메서드를 호출하고 조회된 데이터를 HTML에 바인딩합니다. userHome.html
에서 다음과 같은 jQuery
AJAX 스크립트를 추가합니다.
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>
|
변경 사항을 저장하고 서버를 다시 시작합니다. 유효한 이메일 주소와 비밀번호로 로그인하고 나면 브라우저 콘솔을 통해 다음과 같이 데이터베이스에서 희망사항 목록을 가져왔는지 확인합니다.
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 |
}]
|
이제 JSON
데이터를 순회해 데이터를 HTML에 바인딩해야 합니다. 여기서는 부트스트랩의 list-group
을 이용해 희망사항 목록의 항목을 표시하겠습니다. 다음은 list-group
의 기본 템플릿입니다.
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>
|
userHome.html
의 jumbotron
div에 위의 HTML 코드를 추가합니다. 브라우저에 표시되는 모습은 다음과 같습니다.



이제 각 희망사항 목록마다 위의 list-group
div를 동적으로 생성해 jumbotron
div에 덧붙이기만 하면 됩니다. getWish
함수 호출의 성공 콜백에서 다음과 같은 div를 작성합니다.
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'))); |
여기서는 위의 div를 복사해서 각 희망사항 항목에 대한 list-group
div를 만들겠습니다. 그런 다음 반환된 JSON
문자열을 자바스크립트 객체로 파싱합니다.
1 |
var wishObj = JSON.parse(res); |
이제 wishObj
를 순회해 각 희망사항 항목에 대해 새 div를 복제해서 jumbotron
div에 덧붙입니다.
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 |
});
|
위의 변경 사항을 저장하고 서버를 다시 시작합니다. 유효한 이메일 주소와 비밀번호를 사용해 로그인하면 특정 사용자가 만든 희망사항 목록을 볼 수 있을 것입니다.



정리
이번 튜토리얼에서는 로그인한 사용자가 희망사항을 작성하기위한 인터페이스를 구현했습니다. 또한 사용자 홈 페이지에서 만들어진 희망사항을 가져와 표시하는 데 필요한 메서드와 데이터베이스 저장 프로시저도 구현했습니다.
이번 연재 기사의 4부에서는 사용자 홈 페이지에 표시된 희망사항 목록에 대한 Edit
및 Delete
기능을 구현하는 방법을 살펴보겠습니다.
이 튜토리얼의 소스코드는 깃허브에서 확인하실 수 있습니다.
아래 댓글로 여러분의 생각을 알려주세요!