01204223/flask
- เป็นส่วนหนึ่งของวิชา 01204223
ในขั้นแรกของการฝึกพัฒนาโปรแกรมประยุกต์บนเว็บ เราจะเริ่มโดยการใช้ Flask ที่เป็นเฟรมเวิร์คในการพัฒนาเว็บบน Python ที่มีความเรียบง่าย เพื่อให้เราให้ภาพรวมคร่าว ๆ ก่อน จากนั้นเราจะขยับขยายไปใช้ระบบอื่น ๆ ต่อไป
เอกสารนี้จะเป็นเอกสารประกอบการเรียนด้วยคลิปตามรายการด้านล่าง
- Flask ตอน 1 - เริ่มต้น เรียก server การใช้ route และการ render template เบื้องต้น
- Flask ตอน 2 - การส่งข้อมูลไปยัง template, คำสั่งใน template jinja, การสร้างลิงก์ด้วย tag a, การส่งพารามิเตอร์ทาง url, และการใช้ url_for
- Flask ตอน 3 - การใช้ form ในการส่งข้อมูล การใช้ redirect
เนื้อหา
การติดตั้งและเริ่มเปิดหน้าเว็บ
Flask เป็น library บน python ซึ่งเราจะติดตั้งผ่านทางคำสั่ง pip อย่างไรก็ตาม เราจะพยายามแบ่งส่วนการติดตั้ง library ของ python ให้แยกกันไปตามแต่ละงาน โดยใช้ virtual environment (venv) ดังนั้นก่อนจะติดตั้ง Flask เราจะสร้าง virtual environment ก่อน โดยสั่ง
python -m venv venv
(พารามิเตอร์ venv ตัวแรกเป็นชื่อ module ใน python พารามิเตอร์ venv ตัวที่สองเป็นชื่อไดเร็กทอรีที่จะเก็บ environment ซึ่งเราเปลี่ยนเป็นชื่ออื่นได้)
ถ้าจะเริ่มใช้จะเรียก activate ใน venv/bin/activate (เรียกแตกต่างกันตาม os)
ถ้าเรียก activate แล้ว prompt ใน terminal จะเปลี่ยนไป (ลองสังเกต) จากนั้นเราจะสามารถสั่งให้ติดตั้ง Flask ได้ โดยสั่ง
pip install Flask
Flask จะมาพร้อม development web server เพื่อการพัฒนาและทดสอบเบื้องต้น เราจะเรียกโดยสั่ง
flask run
ซึ่งในตอนแรกถ้าเรายังไม่ได้เขียนอะไร มันจะแสดง error ออกมา
main.py
เราจะเริ่มโดยการสร้าง main.py ดังด้านล่าง
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_world():
return "<p>Hello, World!</p>"
เราต้องตั้งค่าใน environment ก่อนว่าโปรแกรมหลักเราชื่ออะไร
ถ้าใช้ windows สั่ง
set FLASK_APP=main.py
ถ้าใช้ unix (linux,mac) สั่ง
export FLASK_APP=main.py
และสั่งให้ Flask ทำงานใน terminal โดยสั่ง
flask run
จากนั้นเราจะสามารถเปิดเว็บได้ที่ลิงก์ http://localhost:5000 (โดยปกติ Flask จะเปิดเว็บเซิร์ฟเวอร์ไว้ที่พอร์ต 5000)
route
การเรียกใช้งานเว็บแอพลิเคชันทำผ่านทางการส่ง request มาที่ web server โดยสิ่งที่ระบุเป้าหมายของการทำงานคือ url (ดูตรงหัวของ browser) ตัวอย่างของ url เช่น
- http://localhost:5000/
- http://localhost:5000/hello/
- https://theory.cpe.ku.ac.th/wiki/index.php/01204223/flask
ในการเขียน Flask เราจะระบุให้ฟังก์ชันใด เป็นฟังก์ชันที่รับผิดชอบเป้าหมาย (target หรือ end point) ใด ๆ ผ่านทาง annotation @app.route ดังตัวอย่างด้านบนที่เราระบุ
@app.route("/")
ไว้ก่อนฟังก์ชัน ซึ่งเป็นการแจ้งกับ web server ของ Flask ว่าถ้ามี request มาที่ / ให้เรียกใช้ฟังก์ชันดังกล่าว
เราจะเพิ่มอีกฟังก์ชันเพื่อรับ request ที่ /hello/ ดังด้านล่าง
@app.route('/hello/')
def hello_world1():
return 'Hi my name is someone'
การแสดง template
การใช้งาน template
main.py
from flask import Flask
from flask import render_template
from datetime import datetime
app = Flask(__name__)
news_items = {
1: {'id': 1,
'title': 'COVID-19 update',
'body': 'This is a news on COVID-19'},
2: {'id': 2,
'title': 'Facemasks found',
'body': 'Recent news on facemask production'},
3: {'id': 3,
'title':'Python 4',
'body':'Python 4 will be out soon.... this is FAKE'},
}
@app.route('/')
def index():
name = 'Somchai'
time = datetime.now()
return render_template('index.html',
name=name,
time=time,
news_items=news_items.values())
@app.route('/news/<id>/')
def show_news_item(id):
news_item = news_items[int(id)]
return render_template('news_item.html',
id=news_item['id'],
title=news_item['title'],
body=news_item['body'])
templates/index.html
<html>
<body>
<h1>Hello!! {{ name }}</h1>
Hi. This is {{ time }}. This is recent news.
<ul>
{% for item in news_items %}
<li>
<a href="{{ url_for('show_news_item', id=item.id) }}">{{ item.title }}</a>
</li>
{% endfor %}
</ul>
</body>
</html>
templates/show.html
<html>
<body>
<h1>{{ title }}</h1>
<p>{{ body }}</p>
<a href="{{ url_for('index') }}">Home</a>
</body>
</html>
การสร้าง form
main.py
from flask import Flask
from flask import render_template, redirect, url_for
from flask import request
from datetime import datetime
app = Flask(__name__)
news_items = {
1: {'id': 1,
'title': 'COVID-19 update',
'body': 'This is a news on COVID-19'},
2: {'id': 2,
'title': 'Facemasks found',
'body': 'Recent news on facemask production'},
3: {'id': 3,
'title':'Python 4',
'body':'Python 4 will be out soon.... this is FAKE'},
}
@app.route('/')
def index():
name = 'Somchai'
time = datetime.now()
return render_template('index.html',
name=name,
time=time,
news_items=news_items.values())
@app.route('/news/<id>/')
def show_news_item(id):
news_item = news_items[int(id)]
return render_template('news_item.html',
id=news_item['id'],
title=news_item['title'],
body=news_item['body'])
def new_news_item(title, body):
new_id = max(news_items.keys()) + 1
return {
'id': new_id,
'title': title,
'body': body
}
@app.route('/news/create/', methods=['POST'])
def create_news_item():
item = new_news_item(request.form['title'],
request.form['body'])
news_items[item['id']] = item
return redirect(url_for('index'))
templates/index.html
<html>
<body>
<h1>Hello!! {{ name }}</h1>
Hi. This is {{ time }}. This is recent news.
<ul>
{% for item in news_items %}
<li>
<a href="{{ url_for('show_news_item', id=item.id) }}">{{ item.title }}</a>
</li>
{% endfor %}
</ul>
<form action="{{ url_for('create_news_item') }}" method="POST">
Title: <input name="title"/><br />
Body: <textarea name="body"></textarea><br />
<input type="submit" value="Save"/>
</form>
</body>
</html>