美文网首页
一个web应用的诞生(7)--结构调整

一个web应用的诞生(7)--结构调整

作者: 双鱼座的牛 | 来源:发表于2017-06-08 00:14 被阅读0次

    现在所有的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蓝本,方法如下:

    1. 创建main文件夹
    2. 文件夹内新建蓝本初始化文件__init__.py
    3. 创建视图方法文件view.py
    4. 主蓝本内创建错误页视图方法errors.py

    初始化文件代码如下:

    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_*这种方式,在此感谢博友 治电小白菜的提醒。

    当然,最终还要对蓝本进行注册,所以最终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点:(

    相关文章

      网友评论

          本文标题:一个web应用的诞生(7)--结构调整

          本文链接:https://www.haomeiwen.com/subject/unczfxtx.html