现在所有的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)的更多相关文章

  1. 一个web应用的诞生(1)--初识flask

    基于flask的web应用的诞生 Flask是一个非常优秀的web框架,它最大的特点就是保持一个简单而易于扩展的小核心,其他的都有用户自己掌握,并且方便替换,甚至,你可以在社区看到众多开源的,可直接用 ...

  2. 一个web应用的诞生--使用模板

    经过了第一章的内容,已经可以做出一些简单的页面,首先用这种方式做一个登录页面,首先要创建一个login的路由方法: @app.route("/login",methods=[&qu ...

  3. 一个web应用的诞生--美化一下

    经过上一章的内容,其实就页面层来说已结可以很轻松的实现功能了,但是很明显美观上还有很大的欠缺,现在有一些很好的前端css框架,如AmazeUI,腾讯的WeUI等等,这里推荐一个和flask集成很好的b ...

  4. 一个web应用的诞生--数据存储

    上一章实现了登录的部分功能,之所以说是部分功能,是因为用户名和密码写成固定值肯定是不可以的,一个整体的功能,至少需要注册,登录,密码修改等,这就需要提供一个把这些值存储到数据库的能力. 当前的主流数据 ...

  5. 一个web应用的诞生--数据表单

    下面把角色分为两种,普通用户和管理员用户,至少对于普通用户来说,直接修改DB是不可取的,要有用户注册的功能,下面就开始进行用户注册的开发. 用户表 首先要想好用户注册的时候需要提供什么信息:用户名.密 ...

  6. 一个web应用的诞生(6)--用户账户

    之前登录注册的功能都已经完成,但是登录成功回到首页发现还是白茫茫的一片,对的,title一直都写得博客,那么最终目的也是写出一个轻博客来,但是,在发表文章之前是不是要先记录一下登录状态呢? 用户登录 ...

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

    现在所有的Py代码均写在default.py文件中,很明显这种方法下,一旦程序变的负责,那么无论对于开发和维护来说,都会带来很多问题. Flask框架并不强制要求项目使用特定的组织结构,所以这里使用的 ...

  8. 一个web应用的诞生(8)--博文发布

    这个系统一直号称轻博客,但貌似博客的功能还没有实现,这一章将简单的实现一个博客功能,首先,当然是为数据库创建一个博文表(models\post.py): from .. import db from ...

  9. 一个web应用的诞生(9)--回到用户

    在开始之前,我们首先根据之前的内容想象一个场景,用户张三在网上浏览,看到了这个轻博客,发现了感兴趣的内容,于是想要为大家分享一下心情,恩?发现需要注册,好,输入用户名,密码,邮箱,并上传头像后,就可以 ...

  10. 一个web应用的诞生(10)--关注好友

    下面回到首页中,使用一个账户登录,你肯定已经注意到了这里的内容: 没错,现在都是写死的一些固定信息,其中分享数量很容易就可以获取,只需要修改首页模板: <p class="text-m ...

随机推荐

  1. react介绍、环境搭建、demo运行实例

    React官网:https://reactjs.org/docs/create-a-new-react-app.html cnpm网址:http://npm.taobao.org/ 1.react介绍 ...

  2. 【汇总】Windows linux 敏感目录 路径汇总

    日期:2019-08-02 10:53:52 更新:2019-08-19 15:48:01 作者:Bay0net 介绍:中间件.套件等等敏感信息,做个记录. 0x01. 基本信息 遇到文件包含.任意文 ...

  3. MariaDB 连接查询,视图,事物,索引,外键

    1.连接查询 --创建学生表 create table students ( id int unsigned not null auto_increment primary key, name var ...

  4. PHP 异步执行方式

    在工作中我们经常遇到一些比较耗时的任务,比如用户注册发送邮件,审核短信通知等功能,同步执行这些功能的话,响应时间就会变长,所以一般我们会用队列去管理这些功能,但是如果条件不允许怎么办,今天get了一个 ...

  5. 用DotNetDetour HOOK .net类库

    https://github.com/bigbaldy1128/DotNetDetour ------------------------------------------------------- ...

  6. Python学习之表的数据类型

    数据类型 数值类型 类型 大小 范围(有符号) 范围(无符号)unsigned约束 用途 TINYINT 1 字节 (-128,127) (0,255) 小整数值 SMALLINT 2 字节 (-32 ...

  7. Akka系列(四):Akka中的共享内存模型

    前言...... 通过前几篇的学习,相信大家对Akka应该有所了解了,都说解决并发哪家强,JVM上面找Akka,那么Akka到底在解决并发问题上帮我们做了什么呢? 共享内存 众所周知,在处理并发问题上 ...

  8. qt 两种按钮点击事件应用

    1.传统connect 例如: connect(ui->findPushBtn,SIGNAL(clicked()),this,SLOT(find())); 参数1:事件UI 参数2:点击系统函数 ...

  9. HDU 2973 YAPTCHA (威尔逊定理)

    YAPTCHA Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  10. 【3.1】【mysql基本实验】mysql复制(主从复制/异步复制/半同步复制,一主一从)

    关键词:mysql复制(异步复制),mysql异步复制 核心原理: mysql 复制流程原理 一个事务在 mysql异步复制中的流程与生命周期 一个事务,在传统半同步的复制流程 #mysql主从基本实 ...