สรุปสั้น ๆ
จากบทความก่อนหน้านี้ที่เราได้ลองทำ Web Application แบบง่าย ๆ ด้วย Flask พร้อม Deploy ขึ้น Cloud ไปแล้ว ตอนนี้มาดูกันว่า Flask จะมี Library ไหนที่มีประโยชน์และทำให้งานเราง่ายขึ้นบ้างไปดู”
เขียนโดย
Sirasit Boonklang (Aeff)
Tech and Coding Consultant
บทความนี้ตีพิมพ์ และ เผยแพร่เมื่อ 27 เมษายน 2566
โดย 7 ตัวที่เราคัดมาแนะนำตัวเด็ด ๆ จะมีดังนี้ครับ
- Flask-WTF
- Flask-Bootstrap
- Flask-SQLAlchemy
- Flask-Login
- Flask-Admin
- Flask-RESTful
- Flask-Mail
1. Flask-WTF
มาที่ตัวแรกกันเลยกับ Flask-WTF ที่เป็น Library ที่ช่วยในการทำฟอร์มต่าง ๆ ใน Flask ให้ง่ายขึ้น มีเครื่องมือสำหรับสร้างฟอร์ม ตรวจสอบความถูกต้องของฟอร์ม (Form Validation) มาให้พร้อมใช้งานได้เลย
app.py
ตัวอย่างการใช้งาน Flask-WTF และ wtforms ในการกำหนดฟิลด์ของฟอร์มและตรวจสอบข้อมูลเมื่อมีการกด submit
from flask import Flask, render_template, request, redirect, url_for
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret-key'
class NameForm(FlaskForm):
name = StringField('Name')
submit = SubmitField('Submit')
@app.route('/', methods=['GET', 'POST'])
def index():
form = NameForm()
if form.validate_on_submit():
name = form.name.data
return redirect(url_for('greet', name=name))
return render_template('index.html', form=form)
@app.route('/greet/')
def greet(name):
return f'Hello, {name}!'
if __name__ == '__main__':
app.run(debug=True)
index.html
ตัวอย่างหน้าเว็บของฟอร์มรับข้อมูลอย่างง่าย ๆ
<!DOCTYPE html>
<html>
<head>
<title>Flask-WTF Example</title>
</head>
<body>
<h1>Welcome to my website</h1>
<form method="POST" action="{{ url_for('index') }}">
{{ form.csrf_token }}
{{ form.name.label }}
{{ form.name }}
{{ form.submit }}
</form>
</body>
</html>
ผลลัพธ์
2. Flask-SQLAlchemy
ต่อมาตัวที่สอง Flask-SQLAlchemy หากต้องการต่อกับฐานข้อมูลที่เป็น SQL โดย Flask-SQLAlchemy จะมีฟังก์ชันต่าง ๆ ที่ใช้ในการทำงานร่วมกับฐานข้อมูล SQL สามารถเขียนแบบ Object-Relational Mapping (ORM) หรือ SQL statement ก็ได้ ซึ่งทำให้ง่ายต่อการใช้งานกับฐานข้อมูล
app.py
ตัวอย่างการใช้ SQLAlchemy ในการเชื่อมต่อกับฐานข้อมูล SQLite และนำข้อมูลที่ผู้ใช้กรอกผ่านฟอร์มเข้ามา เพิ่มเข้าไปยังฐานข้อมูล พร้อมทั้งนำออกมาแสดงบนหน้าเว็บ
from flask import Flask, render_template, request
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class Book(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(80), nullable=False)
author = db.Column(db.String(80), nullable=False)
year = db.Column(db.Integer, nullable=False)
def __repr__(self):
return f''
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
title = request.form['title']
author = request.form['author']
year = request.form['year']
book = Book(title=title, author=author, year=year)
db.session.add(book)
db.session.commit()
books = Book.query.all()
return render_template('index.html', books=books)
if __name__ == '__main__':
app.run(debug=True)
index.html
ตัวอย่างโค้ดหน้าฟอร์มสำหรับใส่ข้อมูลหนังสือที่ต้องการเก็บไว้ในฐานข้อมูล
<!DOCTYPE html>
<html>
<head>
<title>Flask-SQLAlchemy Example</title>
</head>
<body>
<h1>Books</h1>
<form method="POST">
<label for="title">Title:</label>
<input type="text" id="title" name="title">
<label for="author">Author:</label>
<input type="text" id="author" name="author">
<label for="year">Year:</label>
<input type="number" id="year" name="year">
<button type="submit">Add Book</button>
</form>
<ul>
{% for book in books %}
<li>{{ book.title }} by {{ book.author }}, {{ book.year }}</li>
{% endfor %}
</ul>
</body>
</html>
ตัวอย่างผลลัพธ์ของหน้าเว็บ
3. Flask-Login
เมื่อเรามีการเชื่อมต่อกับฐานข้อมูลแล้ว เราก็มักจะมีระบบที่เป็นหน้า Login สำหรับระบุว่าผู้ใช้งานคนนี้เป็นใครใช่มั้ยครับ เราสามารถใช้งาน Flask-Login ที่มีฟังก์ชันการจัดการ Session สำหรับเว็บ ช่วยลดความยุ่งยากในการเขียนระบบ Login และ Logout ขึ้นมาเอง ทำให้การจัดการ Session ของผู้ใช้ได้อย่างง่าย
app.py
ตัวอย่างการใช้งาน Flask-Login ในการจัดการ User กับข้อมูลตัวอย่าง
from flask import Flask, render_template, request, redirect, url_for
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required
app = Flask(__name__)
app.secret_key = 'your_secret_key_here'
login_manager = LoginManager()
login_manager.init_app(app)
class User(UserMixin):
pass
users = {
'john': {'password': 'password'},
'susan': {'password': 'password'}
}
@login_manager.user_loader
def user_loader(username):
if username not in users:
return
user = User()
user.id = username
return user
@app.route('/')
def index():
return render_template('index.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
if username in users and password == users[username]['password']:
user = User()
user.id = username
login_user(user)
return redirect(url_for('dashboard'))
return 'Invalid username/password combination'
return render_template('login.html')
@app.route('/dashboard')
@login_required
def dashboard():
return render_template('dashboard.html')
@app.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('index'))
if __name__ == '__main__':
app.run(debug=True)
login.html
ตัวอย่างโค้ดหน้า Login อย่างง่าย
<!DOCTYPE html>
<html>
<head>
<title>Login Page</title>
</head>
<body>
<h1>Login</h1>
<form method="POST">
<label for="username">Username:</label>
<input type="text" id="username" name="username" required><br>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required><br>
<input type="submit" value="Login">
</form>
</body>
</html>
ตัวอย่างหน้า Login อย่างง่าย
dashboard.html
ตัวอย่างโค้ดหน้า Dashboard เมื่อผู้ใช้กรอก username และ password ถูกต้อง
<!DOCTYPE html>
<html>
<head>
<title>Dashboard</title>
</head>
<body>
<h1>Welcome to your Dashboard, {{ current_user.id }}!</h1>
<a href="{{ url_for('logout') }}">Logout</a>
</body>
</html>
ตัวอย่างหน้าเว็บ Dashboard เมื่อผู้ใช้กรอก username และ password ถูกต้อง
4. Flask-RESTful
Flask-RESTful เป็นอีก Library ที่ทำให้สร้าง RESTful APIs ได้ง่าย โดยมีเครื่องมือและรูปแบบสำหรับกำหนด resource จัดการคำขอ และจัดลำดับ response ด้วยวิธีที่เป็นไปตามหลักการของ REST
app.py
ตัวอย่างโค้ด CRUD API อย่างง่ายด้วย Flask-RESTful
from flask import Flask
from flask_restful import reqparse, abort, Api, Resource
app = Flask(__name__)
api = Api(app)
TODOS = {
'todo1': {'task': 'build an API'},
'todo2': {'task': '?????'},
'todo3': {'task': 'profit!'},
}
def abort_if_todo_doesnt_exist(todo_id):
if todo_id not in TODOS:
abort(404, message="Todo {} doesn't exist".format(todo_id))
parser = reqparse.RequestParser()
parser.add_argument('task')
# Todo
# shows a single todo item and lets you delete a todo item
class Todo(Resource):
def get(self, todo_id):
abort_if_todo_doesnt_exist(todo_id)
return TODOS[todo_id]
def delete(self, todo_id):
abort_if_todo_doesnt_exist(todo_id)
del TODOS[todo_id]
return '', 204
def put(self, todo_id):
args = parser.parse_args()
task = {'task': args['task']}
TODOS[todo_id] = task
return task, 201
# TodoList
# shows a list of all todos, and lets you POST to add new tasks
class TodoList(Resource):
def get(self):
return TODOS
def post(self):
args = parser.parse_args()
todo_id = int(max(TODOS.keys()).lstrip('todo')) + 1
todo_id = 'todo%i' % todo_id
TODOS[todo_id] = {'task': args['task']}
return TODOS[todo_id], 201
##
## Actually setup the Api resource routing here
##
api.add_resource(TodoList, '/todos')
api.add_resource(Todo, '/todos/')
if __name__ == '__main__':
app.run(debug=True)
ผลลัพธ์
เริ่มจากอ่านข้อมูลทั้งหมด
อ่านเฉพาะ ID นั้น ๆ
เพิ่มข้อมูลไปยัง API
ข้อมูลถูกเพิ่มไปแล้ว
ลบข้อมูล
ข้อมูล todo2 ถูกลบไปแล้ว
อัปเดตข้อมูล
ข้อมูลได้รับการอัปเดตแล้ว
5. Flask-Mail
Flask-Mail เป็น Library ที่มีสำหรับการทำระบบที่มีการส่งข้อความผ่านอีเมล มีฟังก์ชันต่าง ๆ ที่ทำให้ขั้นตอนการส่งข้อความอีเมลง่ายขึ้นและมีวิธีที่ปลอดภัยและเชื่อถือได้ในการส่งข้อความ
app.py
ตัวอย่างโค้ดการส่งอีเมลด้วย Flask โดยใช้ Gmail Server
from flask import Flask
from flask_mail import Mail, Message
def create_app():
app = Flask(__name__)
app.config['MAIL_SERVER'] = 'smtp.gmail.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USERNAME'] = 'example@gmail.com'
app.config['MAIL_PASSWORD'] = 'passwordfromgoogle'
app.config['MAIL_USE_TLS'] = False
app.config['MAIL_USE_SSL'] = True
app.config['MAIL_DEFAULT_SENDER'] = 'example@gmail.com'
mail = Mail()
mail.init_app(app)
@app.route('/')
def index():
msg = Message('Hello From Flask', recipients=['recipient@mail.com'])
mail.send(msg)
return '<h1>Sent!</h1>'
return app
เมื่ออีเมลถูกส่งเรียบร้อยหน้าเว็บจะ return คำว่า Sent กลับมา
และอีเมลจะถูกส่งไปยังผู้รับเรียบร้อย
6. Flask-Admin
Flask-Admin อันนี้เป็น Library ที่มีระบบ Admin เบื้องต้นมาให้ สำหรับดูแลแอปพลิเคชัน Flask ของเรา ช่วยให้จัดการและแก้ไขข้อมูลแอปพลิเคชันของคุณได้อย่างง่ายดายผ่านอินเทอร์เฟซผู้ใช้บนเว็บ
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_admin import Admin
from flask_admin.contrib.sqla import ModelView
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example.db'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
admin = Admin(app, name='My App')
admin.add_view(ModelView(User, db.session))
if __name__ == '__main__':
app.run()
จากโค้ดด้านบนจะเห็นได้ว่าไม่จำเป็นต้องเขียนหน้า admin.html เองเลย ส่วนนี้ก็จะมีการแสดงผลหน้าแอดมินในการจัดการเบื้องต้นมาให้แล้วนั่นเอง
7.Flask-Bootstrap
Flask-Bootstrap เป็นส่วนขยายของ Flask ที่รวมเฟรมเวิร์ก Bootstrap เข้ากับแอปพลิเคชัน Flask ของคุณ Bootstrap เป็นเฟรมเวิร์ก HTML, CSS และ JavaScript ยอดนิยมที่ช่วยในการสร้างหน้าเว็บที่ตอบสนองและรองรับมือถือเป็นอันดับแรก
ด้วย Flask-Bootstrap คุณสามารถเพิ่มไฟล์ Bootstrap CSS และ JavaScript ไปยังแอปพลิเคชัน Flask ของคุณได้อย่างง่ายดาย และใช้เทมเพลตและส่วนประกอบที่กำหนดไว้ล่วงหน้าเพื่อสร้างหน้าเว็บของคุณ
app.py
from flask import Flask, render_template
from flask_bootstrap import Bootstrap
app = Flask(__name__)
bootstrap = Bootstrap(app)
@app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
app.run()
index.html
ผลลัพธ์
มาถึงตรงนี้แล้วจะเห็นได้ว่า Flask มีเครื่องมือหลายตัวที่ทำให้เราสามารถสร้าง Web Application แบบไว ๆ ที่พร้อมใช้งานได้อย่างดายแล้วววว
ระบบฝึกทักษะ การเขียนโปรแกรม
ที่พร้อมตรวจผลงานคุณ 24 ชั่วโมง
- โจทย์ปัญหากว่า 200 ข้อ ที่รอท้าทายคุณอยู่
- รองรับ 9 ภาษาโปรแกรมหลัก ไม่ว่าจะ Java, Python, C ก็เขียนได้
- ใช้งานได้ฟรี ! ครบ 20 ข้อขึ้นไป รับ Certificate ไปเลย !!