Flask入门之完整项目搭建
一、创建虚拟环境
1,新建虚拟环境
cmd中输入:mkvirtualenv 环境名
2,在虚拟环境安装项目运行所需要的基本模块
- pip install flask==0.12.4
- pip install redis
- pip install flask-session
- pip install flask-script
- pip install flask-mysqldb
- pip install flask-sqlalchemy
- pip install flask-migrate
- pip install flask_wtf
二、构建项目文件目录
- 项目根目录/
- ├── application/ # 项目主要逻辑代码保存目录
- | ├── apps #存放蓝图
- | ├── settings/ # 项目配置存储目录
- │ │ ├ dev.py # 开发阶段的配置文件
- │ │ ├ prop.py # 生产阶段的配置文件
- | ├──templates #存放全局的html文件
- │ ├── __init__.py # 项目初始化文件
- ├── manage.py # 项目的终端管理脚本文件
- ├──logs/ #存放日志文件
- ├──docs/ #存放文档文件
三、配置文件
settings/__init__.py:
- from redis import StrictRedis
- class Config(object):
- """项目配置核心类"""
- # 调试模式
- DEBUG = True
- # todo 配置日志
- pass
- # mysql数据库的配置信息
- SQLALCHEMY_DATABASE_URI = "mysql://root:mysql@127.0.0.1:3306/students?charset=utf8"
- # 动态追踪修改设置,如未设置只会提示警告
- SQLALCHEMY_TRACK_MODIFICATIONS = False
- # 查询时会显示原始SQL语句
- SQLALCHEMY_ECHO= False
- # 配置redis
- REDIS_HOST = '127.0.0.1' # 项目上线以后,这个地址就会被替换成真实IP地址,mysql也是
- REDIS_PORT = 6379
- # 设置密钥,可以通过 base64.b64encode(os.urandom(48)) 来生成一个指定长度的随机字符串
- SECRET_KEY = "ghhBljAa0uzw2afLqJOXrukORE4BlkTY/1vaMuDh6opQ3uwGYtsDUyxcH62Aw3ju"
- # flask_session的配置信息
- SESSION_TYPE = "redis" # 指定 session 保存到 redis 中
- SESSION_USE_SIGNER = True # 让 cookie 中的 session_id 被加密签名处理
- SESSION_REDIS = StrictRedis(host=REDIS_HOST, port=REDIS_PORT,db=1) # 使用 redis 的实例
- PERMANENT_SESSION_LIFETIME = 24 * 60 * 60 # session 的有效期,单位是秒
settings/dev.py:
- from . import Config
- class DevelopementConfig(Config):
- """开发模式下的配置"""
- # 查询时会显示原始SQL语句
- SQLALCHEMY_ECHO= True
settings/prop.py:
- from . import Config
- class ProductionConfig(Config):
- """生产模式下的配置"""
- DEBUG = False
四、项目主应用初始化项目
application/__init__.py,创建flask应用并加载配置
- from flask import Flask
- from application.settings.dev import DevelopementConfig
- from application.settings.prop import ProductionConfig
- config = {
- "dev": DevelopementConfig,
- "prop": ProductionConfig,
- }
- def init_app(config_name):
- """项目的初始化函数"""
- app = Flask(__name__)
- # 设置配置类
- Config = config[config_name]
- # 加载配置
- app.config.from_object(Config)
- return app
manage.pyz中调用init_app函数,启动项目
- from application import init_app
- app = init_app("dev")
- @app.route("/")
- def index():
- return "index"
- if __name__ == '__main__':
- app.run()
在application/__init__.py项目初始化文件中加载redis或者mysql的初始化代码
- from flask import Flask
- from redis import StrictRedis
- from flask_wtf.csrf import CSRFProtect
- from flask_session import Session
- from application.settings.dev import DevelopementConfig
- from application.settings.prop import ProductionConfig
- config = {
- "dev": DevelopementConfig,
- "prop": ProductionConfig,
- }
- # 为了方便redis的连接对象在函数外部可以使用,预先设置一个全局变量,接下来在函数中用于保存redis的连接
- redis_store = None
- def init_app(config_name):
- """项目的初始化功能"""
- app = Flask(__name__)
- # 设置配置类
- Config = config[config_name]
- # 加载配置
- app.config.from_object(Config)
- # redis的链接初始化
- global redis_store
- redis_store = StrictRedis(host=Config.REDIS_HOST, port=Config.REDIS_PORT,db=0)
- # 开启CSRF防范功能
- CSRFProtect(app)
- # 开启session功能
- Session(app)
- # TODO 注册蓝图对象到app应用中
- return app
五、增加数据库配置
application/__init__.py增加代码
- # from flask import Flask
- # from redis import StrictRedis
- # from flask_wtf.csrf import CSRFProtect
- # from flask_session import Session
- from flask_sqlalchemy import SQLAlchemy
- #
- # from application.settings.dev import DevelopementConfig
- # from application.settings.prop import ProductionConfig
- #
- # config = {
- # "dev": DevelopementConfig,
- # "prop": ProductionConfig,
- # }
- #
- # # 为了方便redis的连接对象在函数外部可以使用,预先设置一个全局变量,接下来在函数中用于保存redis的连接
- # redis_store = None
- db = SQLAlchemy()
- #
- # def init_app(config_name):
- # """项目的初始化功能"""
- # app = Flask(__name__)
- #
- # # 设置配置类
- # Config = config[config_name]
- #
- # # 加载配置
- # app.config.from_object(Config)
- #
- # # redis的链接初始化
- # global redis_store
- # redis_store = StrictRedis(host=Config.REDIS_HOST, port=Config.REDIS_PORT,db=0)
- #
- # # 开启CSRF防范功能
- # CSRFProtect(app)
- #
- # # 开启session功能
- # Session(app)
- #
- # 配置数据库链接
- db.init_app(app)
- #
- # # TODO 注册蓝图对象到app应用中
- #
- # return app
六、在manage启动文件中新增关于启动过程中的相关功能
manage.py
- from application import init_app,db
- from flask_script import Manager
- from flask_migrate import Migrate, MigrateCommand
- app = init_app("dev")
- # 使用终端脚本工具启动和管理flask
- manager = Manager(app)
- # 启用数据迁移工具
- Migrate(app, db)
- # 添加数据迁移的命令到终端脚本工具中
- manager.add_command('db', MigrateCommand)
- @app.route("/")
- def index():
- return "index"
- if __name__ == '__main__':
- manager.run()
七、日志
application/__init__.py
- import logging
- from logging.handlers import RotatingFileHandler
- # 把日志相关的配置封装成一个日志初始化函数
- def setup_log(Config):
- # 设置日志的记录等级
- logging.basicConfig(level=Config.LOG_LEVEL) # 调试debug级
- # 创建日志记录器,指明日志保存的路径、每个日志文件的最大大小、保存的日志文件个数上限
- file_log_handler = RotatingFileHandler("logs/log", maxBytes=1024 * 1024 * 300, backupCount=10)
- # 创建日志记录的格式 日志等级 输入日志信息的文件名 行数 日志信息
- formatter = logging.Formatter('%(levelname)s %(filename)s:%(lineno)d %(message)s')
- # 为刚创建的日志记录器设置日志记录格式
- file_log_handler.setFormatter(formatter)
- # 为全局的日志工具对象(flaskapp使用的)添加日志记录器
- logging.getLogger().addHandler(file_log_handler)
在init_app方法中电泳上一步创建的方法,并传入config_name
- # 启用日志功能
- setup_log(Config)
在配置文件seetings/__init__.py中,设置日志等级
- class Config(object):
- """项目配置核心类"""
- # 调试模式
- DEBUG = True
- # todo 配置日志
- LOG_LEVEL = "DEBUG"
八、创建蓝图
application下的apps目录专门用于存放蓝图的。创建蓝图
在apps下新建一个包,蓝图名为index,在包下面的__init.py文件中创建蓝图对象
- from flask import Blueprint
- index_blu = Blueprint("index_blu",__name__)
在index蓝图目录下创建对应的视图文件,views.py
- from . import index_blu
- @index_blu.route("/")
- def index():
- return "首页"
在蓝图下的__init__.py文件中引入视图中的所有视图
- from flask import Blueprint
- index_blu = Blueprint("index_blu",__name__)
- from .views import *
在项目初始化文件application/__init__.py文件中注册蓝图对象
- # TODO 注册蓝图对象到app应用中
- # 首页模块
- from .apps.index import index_blu
- app.register_blueprint(index_blu,url_prefix='')
创建模型文件models.py
- # coding=utf-8
- from application import db
- # 创建关系表,不再创建模型,一般用于表与表之间的多对多场景
- """
- 表关系变量 = db.Table(
- "关系表表名",
- db.Column('字段名', 字段类型, 字段选项), # 普通字段
- db.Column("字段名", 字段类型, db.ForeignKey("表名.id")),
- db.Column("字段名", 字段类型, db.ForeignKey("表名.id")),
- )
- """
- achievement = db.Table(
- "achievement",
- db.Column('score', db.Numeric, comment="分数"),
- db.Column('student_id', db.Integer, db.ForeignKey('student.id')),
- db.Column('course_id', db.Integer, db.ForeignKey('course.id'))
- )
- class Student(db.Model):
- """学生信息"""
- __tablename__ = "student"
- id = db.Column(db.Integer, primary_key=True, comment="主键ID")
- name = db.Column(db.String(64), index=True, comment="姓名" )
- sex = db.Column(db.Boolean, default=True, comment="性别")
- class_number = db.Column(db.String(32), nullable=True, index=True, comment="班级")
- age = db.Column(db.SmallInteger, comment="年龄")
- description = db.Column(db.Text, comment="个性签名")
- courses = db.relationship(
- 'Course', # 模型名称
- secondary=achievement, # 表关系变量
- backref='students', # 当外键反过来获取主键信息时,使用的字段名称,可以自定义,接下来的使用例如: course.students 获取某个课程下所有的学生
- lazy='dynamic'
- )
- def __repr__(self):
- return "%s" % self.name
- class Course(db.Model):
- """课程信息"""
- __tablename__ = "course"
- id = db.Column(db.Integer, primary_key=True,comment="主键ID")
- name = db.Column(db.String(64), unique=True,comment="课程名称")
- def __repr__(self):
- return "%s" % self.name
数据库迁移:
- python manage.py db init
- python manage.py db migrate -m 'initial migration'
- python manage.py db upgrade
完成学生表的增删改查
views.py
- from . import index_blu
- from .models import Student
- from flask import render_template,request
- from application import db
- from flask import flash
- @index_blu.route("/")
- def index():
- """學生列表"""
- student_list = Student.query.all()
- data = []
- for student in student_list:
- print(student.sex)
- data.append({
- "id":student.id,
- "name":student.name,
- "age":student.age,
- "sex":"男" if student.sex else "女",
- "description":student.description,
- "class_number":student.class_number,
- })
- return render_template("index.html",students=data)
- @index_blu.route("/add",methods=["POST","GET"])
- def add_student():
- if request.method == "POST":
- # 接受數據
- name = request.form.get("username")
- age = int( request.form.get("age") )
- sex = True if request.form.get("sex") == '' else False
- class_number = request.form.get("class_number")
- description = request.form.get("description")
- # 驗證數據
- if age < 0 or age > 120:
- # 閃現信息[用於返回錯誤信息給客戶端,只顯示一次]
- flash("非法的年齡數值")
- # 保存入庫
- student = Student(name=name,age=age,sex=sex,class_number=class_number,description=description)
- try:
- db.session.add(student)
- db.session.commit()
- except:
- # 事務回滾
- db.session.rollback()
- return render_template("add.html")
在蓝图下创一个templates目录,用于存放自己的模板
在index/__init__.py文件中加入
- #coding=utf-8
- from flask import Blueprint
- index_blu = Blueprint("index_blu",__name__,template_folder="templates")
- from .views import *
这个和django一样的,在查找模板时,先从全局的templates找,然后再去蓝图下面的templates中找
九、闪现信息
使用后,只会出现一次的信息,叫‘闪现信息’,用于在验证数据失败或者一些只需要显示一次性提示得场景。
使用方法:
在视图中当验证有误时,在显示模板之前设置flash
- # 视图函数代码
- from flask import flash
- flash("对不起,您尚未登录,请登录!")
模板中代码:
- # 模板代码
- {% for message in get_flashed_messages() %}
- <span>{{message}}</span>
- {% endfor %}
Flask入门之完整项目搭建的更多相关文章
- SpringBoot之入门教程-SpringBoot项目搭建
SpringBoot大大的简化了Spring的配置,把Spring从配置炼狱中解救出来了,以前天天配置Spring和Mybatis,Springmvc,Hibernate等整合在一起,感觉用起来还是挺 ...
- spring-boot rabbitMq 完整项目搭建,包括创建、发送、监听
写在开始 rabbitMq 代码按照三部分介绍 第一部分 交换机和队列的创建 第二部分 消息发送 第三部分 消息监听 第一部分 1 建立queue 2 建立exchange 3 exchange绑定q ...
- Eclipse+Tomcat+MAVEN+SVN项目完整环境搭建
1.JDK的安装 首先下载JDK,这个从sun公司官网可以下载,根据自己的系统选择64位还是32位,安装过程就是next一路到底.安装完成之后当然要配置环境变量了. ————————————————— ...
- Eclipse4.6(Neon) + Tomcat8 + MAVEN3.3.9 + SVN项目完整环境搭建
软件清单 jdk-8u102-windows-x64.exe eclipse-inst-win64.exe (Eclipse4.6 Neon) apache-tomcat-8.5.5-windows- ...
- Vue项目搭建完整剖析全过程
Vue项目搭建完整剖析全过程 项目源码地址:https://github.com/ballyalex 有帮助的话就加个星星呗~! 项目技术栈:vue+webpack+bower+sass+axios ...
- springboot +mybatis 搭建完整项目
springboot + mybatis搭建完整项目 1.springboot整合mybatis注解版 转:https://blog.csdn.net/u013187139/article/detai ...
- SSM 框架-03-MyEclipse+Tomcat+MAVEN+SVN项目完整环境搭建
SSM 框架-03-MyEclipse+Tomcat+MAVEN+SVN项目完整环境搭建 如果你是使用 Eclipse 你需要先安装 MyEclipse,请参考:SSM 框架-02-MyEclipse ...
- SpringMVC框架入门配置 IDEA下搭建Maven项目(zz)
SpringMVC框架入门配置 IDEA下搭建Maven项目 这个不错哦 http://www.cnblogs.com/qixiaoyizhan/p/5819392.html
- Vue-cli入门(一)——项目搭建
Vue-cli入门(一)——项目搭建 前言: Vue-cli是一款基于vue的项目脚手架工具,其集成了webpack环境和主要的依赖,对于我们的项目搭建.开发.打包.维护管理等都是非常的方便. 主要内 ...
随机推荐
- 使用mongodb的一些笔记
show dbs # 从结果中发现有cmb_demo_23_hackeruse cmb_demo_23_hacker db.all_in_one.find({"_id":15480 ...
- NOIP-接水问题
题目描述 学校里有一个水房,水房里一共装有m个龙头可供同学们打开水,每个龙头每秒钟的供水量相等,均为1. 现在有n名同学准备接水,他们的初始接水顺序已经确定.将这些同学按接水顺序从1到n编号,i号同学 ...
- HTML入门11
在网页中添加矢量图形, 使用矢量图形在很多情况下,效果较好,拥有较小的文件尺寸,高度缩放,下面具体讲解如何在网页中添加矢量图形 位图和矢量图 位图文件包含了每个像素的位置和色彩信息,流行的位图格式包括 ...
- laravel之知识点
- python爬虫第四天
昨天学到了正则表达式基础知识 :原子 今天开始学习第二个基础知识:元字符 元字符 就是正则表达式中含有特殊含义的一些字符 常见的元字符及含义 符号 含义 . 匹配除换行符以外 的任 ...
- 创建Jdbc封装工具类
jdbc.propertie url=jdbc:mysql:///empye user=root password=root driver=com.mysql.jdbc.Driver 读取资源文件 ...
- 2019PHP面试题最全面归纳总结
1.请选择以下代码运行的结果: <?php if ('1e3' == '1000') echo 'LOL'; ?> A 无任何输出结果 B LOL C 不执行且报错 解析:1e3 ...
- barrel_shift
barrel_shift的目的就是在一个bus中根据idx动态选择一部分数据输出如: *dw-:]; -:];// 0~132 *dw-:]; 上面就要求从256的数据单元中选择124个数据单元输出, ...
- 在C++中,setw(int n)
setw(int n)用来控制输出间隔例如:cout<<'s'<<setw(8)<<'a'<<endl;则在屏幕显示s a //s与a之间 ...
- 浅析HSTS
浅析HSTS 一.HSTS是什么? HSTS全称:HTTP Strict Transport Security,意译:HTTP严格传输安全,是一个Web安全策略机制. 二.HSTS解决什么问题? 它解 ...