- 取得連結
- X
- 以電子郵件傳送
- 其他應用程式
程式語言:Python
Flask 官方網站
GitHub
功能:架站
最簡易的程式碼
Flask-Script
Flask-SQLAlchemy
Flask-Admin
Flask-Login
Flask Blueprints
- Package:
- flask
- flask_script
- flask_sqlalchemy
- flask_admin
- flask_login
GitHub
功能:架站
最簡易的程式碼
# hello.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
運行方法
# linux #export FLASK_APP=hello.py # window set FLASK_APP=hello.py python -m flask run
Flask-Script
提供外部指令,例:python manage.py runserver --debug
# hello.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
# manage.py
from flask_script import Manager
from hello import app
manager = Manager(app)
# 自定指令
@manager.command
def hello():
"""Print hello"""
print("hello")
if __name__ == "__main__":
manager.run()
運行方法
# 可確認有哪些指令,自定的指令也會出現 python manage.py # 運行 server python manage.py runserver # 運行 server 並啟動 debug,可輸入 pin 直接 debug python manage.py runserver --debug # 運行 shell python manage.py shell
Flask-SQLAlchemy
ORM 工具,可直接用 python 控制資料庫
# hello.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
# -------------- new -----------------
from flask_sqlalchemy import SQLAlchemy
# 指定資料庫位置
db_uri = 'sqlite:///{}'.format('app.db')
app.config['SQLALCHEMY_DATABASE_URI'] = db_uri
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
def __repr__(self):
return '<User %r>' % self.username
@app.route('/db_demo')
def db_demo():
admin = User(username='admin', email='admin@example.com')
guest = User(username='guest', email='guest@example.com')
db.session.add(admin)
db.session.add(guest)
db.session.commit()
return User.query.filter_by(username='admin').first().username
# -------------- new -----------------
# manage.py
from flask_script import Manager
from hello import app
manager = Manager(app)
@manager.command
def hello():
"""Print hello"""
print("hello")
# -------------- new -----------------
from hello import db
@manager.command
def initDB():
"""Initializes the database."""
db.create_all(bind=None)
# -------------- new -----------------
if __name__ == "__main__":
manager.run()
運行方法# 建立資料庫 python manage.py initDB # demo 網址為:http://127.0.0.1:5000/db_demo python manage.py runserver
Flask-Admin
管理資料庫介面
# hello.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
from flask_sqlalchemy import SQLAlchemy
# 指定資料庫位置
db_uri = 'sqlite:///{}'.format('app.db')
app.config['SQLALCHEMY_DATABASE_URI'] = db_uri
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), nullable=False)
email = db.Column(db.String(120), nullable=False)
def __repr__(self):
return '<User %r>' % self.username
@app.route('/db_demo')
def db_demo():
admin = User(username='admin', email='admin@example.com')
guest = User(username='guest', email='guest@example.com')
db.session.add(admin)
db.session.add(guest)
db.session.commit()
return User.query.filter_by(username='admin').first().username
# -------------- new -----------------
from flask_admin import Admin
from flask_admin.contrib.sqla import ModelView
admin = Admin(app, name='microblog', template_mode='bootstrap3')
admin.add_view(ModelView(User, db.session))
# -------------- new -----------------
# manage.py
from flask_script import Manager
from hello import app
manager = Manager(app)
@manager.command
def hello():
"""Print hello"""
print("hello")
from hello import db
@manager.command
def initDB():
"""Initializes the database."""
db.create_all(bind=None)
if __name__ == "__main__":
manager.run()
運行方法# 介面網址為:http://127.0.0.1:5000/admin/ python manage.py runserver
Flask-Login
提供使用者登入驗證相關工具
# hello.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
from flask_sqlalchemy import SQLAlchemy
# 指定資料庫位置
db_uri = 'sqlite:///{}'.format('app.db')
app.config['SQLALCHEMY_DATABASE_URI'] = db_uri
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), nullable=False)
email = db.Column(db.String(120), nullable=False)
def __repr__(self):
return '<User %r>' % self.username
@app.route('/db_demo')
def db_demo():
admin = User(username='admin', email='admin@example.com')
guest = User(username='guest', email='guest@example.com')
db.session.add(admin)
db.session.add(guest)
db.session.commit()
return User.query.filter_by(username='admin').first().username
from flask_admin import Admin
from flask_admin.contrib.sqla import ModelView
# -------------- new -----------------
from adminView import MyAdminIndexView, Accounts
admin = Admin(app, name='microblog', index_view=MyAdminIndexView(), base_template='backend.html')
import flask_login
class BaseModelView(ModelView):
def is_accessible(self):
return flask_login.current_user.is_authenticated
admin.add_view(BaseModelView(User, db.session))
admin.add_view(BaseModelView(Accounts, db.session))
# -------------- new -----------------
# manage.py
from flask_script import Manager
from hello import app
manager = Manager(app)
@manager.command
def hello():
"""Print hello"""
print("hello")
from hello import db
@manager.command
def initDB():
"""Initializes the database."""
db.create_all(bind=None)
if __name__ == "__main__":
manager.run()
新增 adminView.py
# adminView.py
from flask import url_for, redirect, request
from wtforms import form, fields, validators
from flask_admin import Admin, AdminIndexView, helpers, expose
from flask_login import LoginManager, current_user, login_user, logout_user
from werkzeug.security import generate_password_hash, check_password_hash
from hello import db, app
# os.urandom(24)
app.config['SECRET_KEY'] = b'\xe1\xa9\x7f9\xa6\x9cwe\xd01\x00\x18\xc2.\xad\x81\xf97Y\xd4wK9P'
# Create user model.
class Accounts(db.Model):
# 若不寫則看 class name
__tablename__ = 'accounts'
# 設定 primary_key
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(120))
password = db.Column(db.String(64))
# Flask-Login integration
def is_authenticated(self):
return True
def is_active(self):
return True
def is_anonymous(self):
return False
# for @login_manager.user_loader 使用
def get_id(self):
return self.id
def __repr__(self):
return '<Accounts {}>'.format(self.username)
# 登入表格
class LoginForm(form.Form):
username = fields.TextField(validators=[validators.required()])
password = fields.PasswordField(validators=[validators.required()])
def validate_username(self, field):
user = self.get_user()
if user is None:
raise validators.ValidationError('Invalid user')
# we're comparing the plaintext pw with the the hash from the db
if not check_password_hash(user.password, self.password.data):
# to compare plain text passwords use
# if user.password != self.password.data:
raise validators.ValidationError('Invalid password')
def get_user(self):
return db.session.query(Accounts).filter_by(username=self.username.data).first()
# 註冊表格
class RegistrationForm(form.Form):
username = fields.TextField(validators=[validators.required()])
email = fields.TextField()
password = fields.PasswordField('New Password', [validators.DataRequired(),
validators.EqualTo('confirm', message='Passwords must match')
])
confirm = fields.PasswordField('Repeat Password')
def validate_username(self, field):
if db.session.query(Accounts).filter_by(username=self.username.data).count() > 0:
raise validators.ValidationError('Duplicate username')
# 初始登入
def init_login():
login_manager = LoginManager()
login_manager.init_app(app)
# Create user loader function
@login_manager.user_loader
def load_user(user_id):
return db.session.query(Accounts).get(user_id)
# 建立 admin 的登入介面
class MyAdminIndexView(AdminIndexView):
@expose('/')
def index(self):
if not current_user.is_authenticated:
return redirect(url_for('.login_view'))
return super(MyAdminIndexView, self).index()
@expose('/login/', methods=('GET', 'POST'))
def login_view(self):
# handle user login
form = LoginForm(request.form)
if helpers.validate_form_on_submit(form):
user = form.get_user()
login_user(user)
if current_user.is_authenticated:
return redirect(url_for('.index'))
link = '<p>Don\'t have an account? <a href="' + url_for('.register_view') + '">Click here to register.</a></p>'
self._template_args['form'] = form
self._template_args['link'] = link
return super(MyAdminIndexView, self).index()
@expose('/register/', methods=('GET', 'POST'))
def register_view(self):
form = RegistrationForm(request.form)
if helpers.validate_form_on_submit(form):
user = Accounts()
form.populate_obj(user)
# we hash the users password to avoid saving it as plaintext in the db,
# remove to use plain text:
user.password = generate_password_hash(form.password.data)
db.session.add(user)
db.session.commit()
login_user(user)
return redirect(url_for('.index'))
link = '<p>Already have an account? <a href="' + url_for('.login_view') + '">Click here to log in.</a></p>'
self._template_args['form'] = form
self._template_args['link'] = link
return super(MyAdminIndexView, self).index()
@expose('/logout/')
def logout_view(self):
logout_user()
return redirect(url_for('.index'))
# Initialize flask-login
init_login()
新增 backend.html{% extends 'admin/base.html' %}
{% block access_control %}
{% if current_user.is_authenticated %}
<div class="btn-group pull-right">
<a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
<i class="icon-user"></i> {{ current_user.login }} <span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="{{ url_for('admin.logout_view') }}">Log out</a></li>
</ul>
</div>
{% endif %}
{% endblock %}
新增 admin/index.html{% extends 'admin/master.html' %}
{% block body %}
{{ super() }}
<div class="row-fluid">
<div>
{% if current_user.is_authenticated %}
<p class="lead">
Authentication
</p>
<p>
{{ current_user }} Example
</p>
{% else %}
<form method="POST" action="">
{{ form.hidden_tag() if form.hidden_tag }}
{% for f in form if f.type != 'CSRFTokenField' %}
<div>
{{ f.label }}
{{ f }}
{% if f.errors %}
<ul>
{% for e in f.errors %}
<li>{{ e }}</li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endfor %}
<button class="btn" type="submit">Submit</button>
</form>
{{ link | safe }}
{% endif %}
</div>
<a class="btn btn-primary" href="/"><i class="icon-arrow-left icon-white"></i> Back</a>
</div>
{% endblock body %}
運行方法# 介面網址為:http://127.0.0.1:5000/admin/ python manage.py runserver
Flask Blueprints
將 view 額外拆成另一個檔案 view.py,以便管理
# hello.py from flask import Flask from view import simple_page app = Flask(__name__) app.register_blueprint(simple_page)
# manage.py
from flask_script import Manager
from hello import app
manager = Manager(app)
if __name__ == "__main__":
manager.run()
# view.py
from flask import Blueprint
simple_page = Blueprint('simple_page', __name__,
template_folder='templates')
@simple_page.route('/')
def hello_world():
return 'Hello, World!'
留言
張貼留言