现在所有的Py代码均写在default.py文件中,很明显这种方法下,一旦程序变的负责,那么无论对于开发和维护来说,都会带来很多问题。
Flask框架并不强制要求项目使用特定的组织结构,所以这里使用的组织结构并不一定与其它项目中相同。
根据default.py中的代码,大体可分为三类:表单模型,数据模型,视图方法,所以模型也网这类中来区分。所以按照其他语言(java)得来的经验,每个类为一个py文件,放到相应的文件夹中
在单个文件中,所有的配置都写在单个的文件里,而在进行多文件重构之后,还这样做很明显是不合适的,所以创建一个独立的config文件很有必要:
1
2
3
4
5
6
|
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):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
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蓝本,方法如下:
- 创建main文件夹
- 文件夹内新建蓝本初始化文件__init__.py
- 创建视图方法文件view.py
- 主蓝本内创建错误页视图方法errors.py
初始化文件代码如下:
1
2
3
4
|
from flask import Blueprint
main = Blueprint( "main" ,__name__) # 创建蓝本
from . import errors,views
|
目前,视图方法文件只有一个index方法,代码如下:
1
2
3
4
5
6
|
from flask import render_template
from . import main
@main .route( "/" )
def index():
return render_template( "index.html" ,site_name = 'myblog' )
|
错误页代码略
主蓝本的的URL不使用前缀
然后登陆注册登出页集中到权限蓝本(auth),权限蓝本初始化代码如下:
1
2
3
4
|
from flask import Blueprint
auth = Blueprint( "auth" ,__name__)
from . import views
|
视图主要为之前已经完成的视图迁移过来:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
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文件内的代码如下:
1
2
3
4
5
6
7
8
9
|
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文件内的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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方法的代码为:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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文件,配置启动代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
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的时候相同,此时系统目录如下,仅供参考:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。