프로그래밍/Python
[파이썬3 웹프로그래밍] Flask & MongoDB 응용
Sanghou
2017. 10. 11. 12:01
In [1]:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run(port=5000,debug = True)
## Jupyter Notebook에서는 debug시 에러가 뜸
이 코드는 무슨 일을 한것인가?
Flask(name)
Flask
class를 물려받았다.
@app.route('/')
데코레이터 (@)
를 이용해서 Flask에게 어떤 URL이 우리가 작성한 함수를 실행하는지 알려준다.데코레이터 (@)
란 대상 함수를 wrapping 하고, 이 wrapping 된 함수의 앞뒤에 추가적으로 꾸며질 구문 들을 정의해서 손쉽게 재사용 가능하게 해주는 것이다. 참고- 파라미터인
'/'
는 URL을 나타낸다.
- run(port=5000,debug = True)
- 최종적으로
run()
함수를 통해 어플리케이션을 로컬서버로 실행한다. - parameter
port=
는 어떤 로컬 서버로 실행할지를 나타내는 주소다. - parameter
debug=
는 코드 변경이 있을 때 Flask 서버 자체적으로 이를 감지하고 리로드할지에 대한 것을 설정할 수 있다.
- 최종적으로
1.1.2. 예제로 보는 Flask 구조 짜보기¶
일단 이 사이트를 들어 가볼까요?
뒤에 있는 .jsp는 back-end로 자바를 사용한 것이니 그 이전까지를 사용해서 server.py를 구성해봅시다.
기본 URL은 http://ebiz.ajou.ac.kr 라고 가정합니다!
In [2]:
from flask import Flask, render_template
app = Flask(__name__)
# http://ebiz.ajou.ac.kr/ebiz/
@app.route('/ebiz/')
def main():
return render_template('main.html')
if __name__ == '__main__':
app.run(port=5000,debug = True)
Quiz1¶
자 그러면
학과소개
,교육
,교수진
,학생활동
,커뮤니티
에 대해서 URL을 정의해 봅시다! (구조만 짜보는 것으로, route부분과 함수이름, 그리고 return 부분을 건드려 주세요~)조건1 : .html은 함수이름과 같게 만들어주세요
조건2 : .jsp부분은 URL에서 없는 걸로하고 진행해주세요
- 그리고 main.html도 바꿔줘야 한답니다.
- 여기서 사용되는 것이 바로 Jinja2 문법
In [3]:
from pymongo import MongoClient
client = MongoClient()
db = client["test"] # 새로운 엑셀 파일로 생각하시면 됩니다~
collection = db.restaurants # 새 시트 만들기로 생각하시면 됩니다~
- MongoDB에서의 대응 관계
- db는 새로운 데이터 베이스 전체를 만든 것입니다.
- collection은 db에서 정의한 데이터 베이스 내에서 새로운 데이터 테이블을 만드는 것입니다.
- collection = client.test.restaurants로도 표현할 수가 있습니다.
1.2.2. Insert¶
In [4]:
new_documents = [
{
"name": "Sun Bakery Trattoria",
"stars": 4,
"categories": ["Pizza","Pasta","Italian","Coffee","Sandwiches"]
}, {
"name": "Blue Bagels Grill",
"stars": 3,
"categories": ["Bagels","Cookies","Sandwiches"]
}, {
"name": "Hot Bakery Cafe",
"stars": 4,
"categories": ["Bakery","Cafe","Coffee","Dessert"]
}, {
"name": "XYZ Coffee Bar",
"stars": 5,
"categories": ["Coffee","Cafe","Bakery","Chocolates"]
}, {
"name": "456 Cookies Shop",
"stars": 4,
"categories": ["Bakery","Cookies","Cake","Coffee"]
}
]
# collection.insert_many(new_documents)
1.2.3. Query¶
In [11]:
for restaurant in collection.find({'stars' : 3}):
print(restaurant)
1.2.4. skip().limit()¶
In [12]:
result = collection.find().skip(0).limit(5)
for post in result:
print(post)
2. blog 예제¶
- To do list
- 블로그 구조를 server.py로 코드로 작성해본다.
- MongoDB와 연동하여 데이터의 입출력을 코드로 구현한다.
- Jinja2 문법을 통해 html을 효율적으로 이용해본다.
- 글쓰기, 글수정, 글삭제 기능을 구현해본다.
- 블로그 구조 {함수 (url)}
main ('/')
: 글쓰기, 수정, 삭제 버튼이 있고, 글목록이 보임add ('/add')
: 글쓰기 페이지update ('/update')
: 글수정 페이지delete ('/delete')
: 글삭제 페이지
- 준비물
- html
- css
2.1. Main & add 페이지¶
In [15]:
from pymongo import MongoClient
from flask import Flask, render_template
app = Flask(__name__)
client = MongoClient()
db = client.Flask # MongoClient 아무거나 점찍고 뒤에 쓸 수 있음
collection = db.blog # collection
@app.route('/')
def main():
return render_template('main.html')
@app.route('/add')
def add():
return render_template('add.html')
if __name__ == '__main__':
app.run(debug=True)
우선 add()
에서는 실제로 저장 버튼을 눌렀을 때 db에 데이터가 저장되어야합니다.
그렇기에 안에 내용을 추가해야하는데, 아래 코드를 보도록 합시다.
- add() 코드 변경
In [ ]:
from flask import Flask, render_template, request, redirect
@app.route('/add', methods=['POST', 'GET'])
def add():
if request.method == 'POST':
collection.save({
"title": request.form["title"],
"content": request.form["content"]
})
return redirect('/')
else: # GET 방식을 의미합니다.
return render_template('add.html')
갑자기 왜이렇게 늘어났죠....?
GET하고 POST는 또 뭐죠
GET과 POST
GET과 POST는 HTTP프로토콜을 이용해서 서버에 무언가를 전달할 때 사용하는 방식입니다. 출처 및 참고
GET
: 대체로 POST 이전에 수행되는 method로 단순히 서버에서 어떤 데이터를 가져와서 보여주는 용도입니다.POST
: 대체로 GET 이후에 수행되는 method로 서버의 값이나 상태를 바꾸기 위해 사용합니다.
- 이 코드는 무슨일을 하는가?
- 간단하게 말하자면 처음에는
GET
방식으로 템플릿을 보여주고, 저장 버튼을 누르면POST
방식으로 데이터를 MongoDB의 collection으로 전달합니다. - request.method : 현재 요청이
GET
인지POST
인지 구별 - collection.save : 만든 데이터 베이스에 데이터를 저장해줍니다.
- request.form :
add.html
에서 정보를 가져옵니다.
- request.form :
- redirect :
POST
에서의 작업이 끝났다면 다시 Main 페이지로 보내기 위함
- 간단하게 말하자면 처음에는
자 그러면 수정하고 실행해봅시다!
In [ ]:
from pymongo import MongoClient
client = MongoClient()
db = client.Flask # MongoClient 아무거나 점찍고 뒤에 쓸 수 있음
collection = db.blog # collection
for post in colletion.find():
print(post)
- Main()도 바꿔야겠죠?
In [14]:
@app.route('/')
def main():
posts = collection.find().skip(0).limit(20)
return render_template('main.html', posts=posts)
- 그리고 main.html도 바꿔줘야 한답니다.
- 여기서 사용되는 것이 바로 Jinja2 문법
In [ ]:
{% for post in posts %}
<main class="contents">
<article class="card">
<h1>{{post.title}}</h1>
<p>{{post.content}}</p>
</article>
</main>
{% endfor %}
- 전체 server.py 코드
In [ ]:
from pymongo import MongoClient
from flask import Flask, render_template, request, redirect
app = Flask(__name__)
client = MongoClient()
db = client.Flask # MongoClient 아무거나 점찍고 뒤에 쓸 수 있음
collection = db.blog # collection
@app.route('/')
def main():
posts = collection.find().skip(0).limit(20)
return render_template('main.html', posts=posts)
@app.route('/add', methods=['POST', 'GET'])
def add():
if request.method == 'POST':
collection.save({
"title": request.form["title"],
"content": request.form["content"]
})
return redirect('/')
else: # GET 방식을 의미합니다.
return render_template('add.html')
@app.route('/update', methods=['POST','GET'])
def update():
if request.method == 'POST':
collection.save({
"_id": ObjectId(request.form["_id"]),
"title": request.form["title"],
"content": request.form["content"]
})
return redirect('/')
else: #GET
_id = request.args.get('_id', '')
post = collection.find_one({"_id": ObjectId(_id)})
return render_template('detail.html', post = post)
@app.route('/delete/<_id>',methods=['POST','GET'])
def delete(_id):
if request.method == 'POST':
collection.remove({"_id":ObjectId(_id)})
return redirect('/')
else:
post = collection.find_one({"_id": ObjectId(_id)})
return render_template('delete-check.html', post = post)
if __name__ == '__main__':
app.run(port=5001, debug=True)