- 取得連結
- 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 -----------------
新增 adminView.py
- # 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()
新增 backend.html
- # 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()
新增 admin/index.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 %}
運行方法
- {% 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!'
留言
張貼留言