如今全部的Py代碼均寫在default.py文件中,很明顯這種方法下,一旦程序變的負責,那麼不管對於開發和維護來講,都會帶來不少問題。html
Flask框架並不強制要求項目使用特定的組織結構,因此這裏使用的組織結構並不必定與其它項目中相同。java
根據default.py中的代碼,大致可分爲三類:表單模型,數據模型,視圖方法,因此模型也網這類中來區分。因此按照其餘語言(java)得來的經驗,每一個類爲一個py文件,放到相應的文件夾中mysql
在單個文件中,全部的配置都寫在單個的文件裏,而在進行多文件重構以後,還這樣作很明顯是不合適的,因此建立一個獨立的config文件頗有必要:面試
class Config: SECRET_KEY="Niu_blog String" SQLALCHEMY_DATABASE_URI='mysql://root:1234@localhost/cblog' SQLALCHEMY_COMMIT_ON_TEARDOWN=True LOGIN_PROTECTION="strong" LOGIN_VIEW="login"
而後是初始化文件(app/__init__.py):sql
from flask import Flask from flask_bootstrap import Bootstrap from flask_sqlalchemy import SQLAlchemy from flask_login import LoginManager import pymysql pymysql.install_as_MySQLdb() from config import Config bootstrap = Bootstrap() db = SQLAlchemy() login_manager=LoginManager(); def create_app(): app = Flask(__name__) app.config.from_object(Config) bootstrap.init_app(app) login_manager.init_app(app) login_manager.session_protection=Config.LOGIN_PROTECTION login_manager.login_view=Config.LOGIN_VIEW db.init_app(app) return app
進一步模塊化還要使用藍本,藍本的功能有些相似 asp.net mvc中的area,將不一樣模塊的視圖方法整合到一塊兒,並經過url進行區分,首先入口即index頁面定義爲main藍本,方法以下:shell
初始化文件代碼以下:數據庫
from flask import Blueprint main=Blueprint("main",__name__) # 建立藍本 from . import errors,views
目前,視圖方法文件只有一個index方法,代碼以下:flask
from flask import render_template from . import main @main.route("/") def index(): return render_template("index.html",site_name='myblog')
錯誤頁代碼略bootstrap
主藍本的的URL不使用前綴session
而後登錄註冊登出頁集中到權限藍本(auth),權限藍本初始化代碼以下:
from flask import Blueprint
auth=Blueprint("auth",__name__) from . import views
視圖主要爲以前已經完成的視圖遷移過來:
from . import auth from .. import db,login_manager from ..forms.LoginForm import LoginForm(*) from ..models.User import User (*) from flask_login import login_user,logout_user from flask import render_template,flash,redirect,url_for @auth.route("/login",methods=["GET","POST"]) def login(): form = LoginForm() print(url_for("main.index")) if form.validate_on_submit(): username = form.username.data password = form.password.data print(User) user = User.query.filter_by(username=username, password=password).first() if user is not None: login_user(user, form.remember_me.data) print(url_for("main.index")) return redirect(url_for("main.index")) else: flash("您輸入的用戶名或密碼錯誤") return render_template("/auth/login.html", form=form) # 返回的仍爲登陸頁 return redirect(url_for("main.index")) return render_template("/auth/login.html",form=form) @auth.route("/logout",methods=["GET","POST"]) def logout(): logout_user() return redirect(url_for("main.index")) @login_manager.user_loader def load_user(user_id): return User.query.get(int(user_id))
注意打星號標記的兩行,必定要注意py文件和py對象,必須在文件內在import對象
其中LoginForm文件內的代碼以下:
from flask_wtf import FlaskForm from wtforms import StringField,PasswordField,SubmitField,BooleanField from wtforms.validators import DataRequired class LoginForm(FlaskForm): username=StringField("請輸入用戶名",validators=[DataRequired()]) password=PasswordField("請輸入密碼") remember_me=BooleanField("記住我") submit=SubmitField("登陸")
User文件內的代碼以下:
from flask_login import UserMixin from .. import db class User(UserMixin,db.Model): __tablename__="users" id=db.Column(db.Integer,primary_key=True) username=db.Column(db.String(50),unique=True,index=True) password=db.Column(db.String(50)) nickname=db.Column(db.String(50)) email=db.Column(db.String(100)) birthday=db.Column(db.DateTime) gender=db.Column(db.Integer) remark=db.Column(db.String(200)) role_id=db.Column(db.Integer,db.ForeignKey("roles.id"))
注意一下flask插件的導入方式都由flask.ext.*改成新版本推薦的flask_*這種方式,在此感謝博友 治電小白菜的提醒。
固然,最終還要對藍本進行註冊,因此最終create_app方法的代碼爲:
def create_app(): app = Flask(__name__) app.config.from_object(Config) bootstrap.init_app(app) login_manager.init_app(app) login_manager.session_protection=Config.LOGIN_PROTECTION login_manager.login_view=Config.LOGIN_VIEW db.init_app(app) from .main import main as main_blueprint from .auth import auth as auth_blueprint app.register_blueprint(main_blueprint) #無url前綴 app.register_blueprint(auth_blueprint,url_prefix="/auth") #url前綴爲/auth return app
最後修改的是啓動運行的方式,新建一個manager.py文件,配置啓動代碼以下:
from app import create_app, db from flask_script import Manager,Shell from flask_migrate import Migrate,MigrateCommand from app.models.User import User from app.models.Role import Role import pymysql pymysql.install_as_MySQLdb() app=create_app() manager=Manager(app); migrate = Migrate(app, db) def make_shell_context(): return dict(app=app,db=db,User=User,Role=Role) #註冊shell命令 manager.add_command("db", MigrateCommand) #新增db命令用於數據庫遷移 manager.add_command("shell" ,Shell(make_context=make_shell_context())) if __name__ =='__main__': manager.run()
用最土的方式,跑跑運行一下,運行結果與以前僅有default.py的時候相同,此時系統目錄以下,僅供參考:
此章並無多少新東西,主要是對以前的系統目錄,系統結構作一些調整,這周比較忙,要準備應聘,準備面試,緊趕慢趕總算至少完成了對本身的承諾,每週一篇blog,不過若是按照發布時間來講,貌似仍是晚了一天,畢竟如今已通過了0點:(