- 取得連結
- 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!'
留言
張貼留言