一個(gè)基于flask的web應(yīng)用誕生 組織結(jié)構(gòu)調(diào)整(7)
現(xiàn)在所有的Py代碼均寫(xiě)在default.py文件中,很明顯這種方法下,一旦程序變的負(fù)責(zé),那么無(wú)論對(duì)于開(kāi)發(fā)和維護(hù)來(lái)說(shuō),都會(huì)帶來(lái)很多問(wèn)題。
Flask框架并不強(qiáng)制要求項(xiàng)目使用特定的組織結(jié)構(gòu),所以這里使用的組織結(jié)構(gòu)并不一定與其它項(xiàng)目中相同。
根據(jù)default.py中的代碼,大體可分為三類(lèi):表單模型,數(shù)據(jù)模型,視圖方法,所以模型也網(wǎng)這類(lèi)中來(lái)區(qū)分。所以按照其他語(yǔ)言(java)得來(lái)的經(jīng)驗(yàn),每個(gè)類(lèi)為一個(gè)py文件,放到相應(yīng)的文件夾中
在單個(gè)文件中,所有的配置都寫(xiě)在單個(gè)的文件里,而在進(jìn)行多文件重構(gòu)之后,還這樣做很明顯是不合適的,所以創(chuàng)建一個(gè)獨(dú)立的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):
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
進(jìn)一步模塊化還要使用藍(lán)本,藍(lán)本的功能有些類(lèi)似 asp.net mvc中的area,將不同模塊的視圖方法整合到一起,并通過(guò)url進(jìn)行區(qū)分,首先入口即index頁(yè)面定義為main藍(lán)本,方法如下:
- 創(chuàng)建main文件夾
- 文件夾內(nèi)新建藍(lán)本初始化文件__init__.py
- 創(chuàng)建視圖方法文件view.py
- 主藍(lán)本內(nèi)創(chuàng)建錯(cuò)誤頁(yè)視圖方法errors.py
初始化文件代碼如下:
from flask import Blueprint main=Blueprint("main",__name__) # 創(chuàng)建藍(lán)本 from . import errors,views
目前,視圖方法文件只有一個(gè)index方法,代碼如下:
from flask import render_template from . import main @main.route("/") def index(): return render_template("index.html",site_name='myblog')
錯(cuò)誤頁(yè)代碼略
主藍(lán)本的的URL不使用前綴
然后登陸注冊(cè)登出頁(yè)集中到權(quán)限藍(lán)本(auth),權(quán)限藍(lán)本初始化代碼如下:
from flask import Blueprint auth=Blueprint("auth",__name__) from . import views
視圖主要為之前已經(jīng)完成的視圖遷移過(guò)來(lái):
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("您輸入的用戶名或密碼錯(cuò)誤") return render_template("/auth/login.html", form=form) # 返回的仍為登錄頁(yè) 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))
注意打星號(hào)標(biāo)記的兩行,一定要注意py文件和py對(duì)象,必須在文件內(nèi)在import對(duì)象
其中LoginForm文件內(nèi)的代碼如下:
from flask_wtf import FlaskForm from wtforms import StringField,PasswordField,SubmitField,BooleanField from wtforms.validators import DataRequired class LoginForm(FlaskForm): username=StringField("請(qǐng)輸入用戶名",validators=[DataRequired()]) password=PasswordField("請(qǐng)輸入密碼") remember_me=BooleanField("記住我") submit=SubmitField("登錄")
User文件內(nèi)的代碼如下:
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插件的導(dǎo)入方式都由flask.ext.*改為新版本推薦的flask_*這種方式,在此感謝博友 治電小白菜的提醒。
當(dāng)然,最終還要對(duì)藍(lán)本進(jìn)行注冊(cè),所以最終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) #無(wú)url前綴 app.register_blueprint(auth_blueprint,url_prefix="/auth") #url前綴為/auth return app
最后修改的是啟動(dòng)運(yùn)行的方式,新建一個(gè)manager.py文件,配置啟動(dòng)代碼如下:
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) #注冊(cè)shell命令 manager.add_command("db", MigrateCommand) #新增db命令用于數(shù)據(jù)庫(kù)遷移 manager.add_command("shell" ,Shell(make_context=make_shell_context())) if __name__ =='__main__': manager.run()
用最土的方式,跑跑運(yùn)行一下,運(yùn)行結(jié)果與之前僅有default.py的時(shí)候相同,此時(shí)系統(tǒng)目錄如下,僅供參考:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python 調(diào)用 zabbix api的方法示例
這篇文章主要介紹了Python 調(diào)用 zabbix api的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-01-01用python3 urllib破解有道翻譯反爬蟲(chóng)機(jī)制詳解
這篇文章主要介紹了python破解網(wǎng)易反爬蟲(chóng)機(jī)制詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08python 實(shí)現(xiàn)rolling和apply函數(shù)的向下取值操作
這篇文章主要介紹了python 實(shí)現(xiàn)rolling和apply函數(shù)的向下取值操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-06-06Python PyQt5實(shí)現(xiàn)拖放效果的原理詳解
這篇文章主要為大家詳細(xì)介紹了Python PyQt5中拖放效果的實(shí)現(xiàn)原理與實(shí)現(xiàn)代碼,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-11-11Pandas中Series的創(chuàng)建及數(shù)據(jù)類(lèi)型轉(zhuǎn)換
這篇文章主要介紹了Pandas中Series的創(chuàng)建及數(shù)據(jù)類(lèi)型轉(zhuǎn)換,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-08-08python協(xié)程之動(dòng)態(tài)添加任務(wù)的方法
今天小編就為大家分享一篇python協(xié)程之動(dòng)態(tài)添加任務(wù)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-02-02Python?Celery定時(shí)任務(wù)詳細(xì)講解
這篇文章主要介紹了Python?Celery定時(shí)任務(wù)詳細(xì)講解,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-08-08python實(shí)現(xiàn)代碼統(tǒng)計(jì)器
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)代碼統(tǒng)計(jì)器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09使用python將圖片格式轉(zhuǎn)換為ico格式的示例
今天小編就為大家分享一篇使用python將圖片格式轉(zhuǎn)換為ico格式的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-10-10