现在所有的 Py 代码均写在 default.py 文件中,很明显这种方法下,一旦程序变的负责,那么无论对于开发和维护来说,都会带来很多问题。
Flask 框架并不强制要求项目使用特定的组织结构,所以这里使用的组织结构并不一定与其它项目中相同。
根据 default.py 中的代码,大体可分为三类:表单模型,数据模型,视图方法,所以模型也网这类中来区分。所以按照其他语言(java)得来的经验,每个类为一个 py 文件,放到相应的文件夹中
在单个文件中,所有的配置都写在单个的文件里,而在进行多文件重构之后,还这样做很明显是不合适的,所以创建一个独立的 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
进一步模块化还要使用蓝本,蓝本的功能有些类似 asp.net mvc 中的 area,将不同模块的视图方法整合到一起,并通过 url 进行区分,首先入口即 index 页面定义为 main 蓝本, 方法如下:
初始化文件代码如下:
- from flask import Blueprint
- main=Blueprint("main",__name__) # 创建蓝本
- from . import errors,views
目前,视图方法文件只有一个 index 方法,代码如下:
- from flask import render_template
- from . import main
- @main.route("/")
- def index():
- return render_template("index.html",site_name='myblog')
错误页代码略
主蓝本的的 URL 不使用前缀
然后登陆注册登出页集中到权限蓝本(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_* 这种方式, 在此感谢博友 治电小白菜的提醒。
最后修改的是启动运行的方式,新建一个 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 点:(
来源: http://www.cnblogs.com/jiangchao226/p/6464118.html