Flask项目结构化调整(五)

 ̄綄美尐妖づ 提交于 2019-11-26 09:28:24

Flask项目结构化

FlaskDirectory
	|----FlaskDirectory
			|----static
		    |----templates
		    |----main.py
		    |----models.py
		    |----view.py
		    |----manage.py

这里需要注意:必须在flask项目下再创建一个项目同名目录,用于存储flask项目文件,否则包导入就会有问题。所有的包导入都是针对该项目目录下的,直接使用项目目录用不了。
在这里插入图片描述
我们依照Django的项目层级思想,在flask项目上对其进行结构化:
模板文件目录和静态文件目录跟django没有太大变化
然后创建程序入口文件main.py,并将入口代码放入
在这里插入图片描述

import os
import pymysql
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

pymysql.install_as_MySQLdb()

app = Flask(__name__)

BASE_DIR = os.path.abspath(os.path.dirname(__file__))

# app.config返回类字典对象,里面用来存放当前app实例的配置
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///"+os.path.join(BASE_DIR,"Student.sqlite")
app.config["SQLALCHEMY_COMMIT_ON_TEARDOWN"] = True
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True

# 关联sqlalchemy和flask应用
db = SQLAlchemy(app)

再创建数据模型类文件models.py
在这里插入图片描述

from FlaskDirectory.main import db

# 创建数据库回话,基于会话进行增删改查
session = db.session()

class BaseModel(db.Model):
    __abstract__ = True # 抽象表为True,代表当前类为抽象类,不会被创建
    id = db.Column(db.Integer,primary_key=True,autoincrement=True)

    # 数据保存方法
    def save(self):
        session.add(self)
        session.commit()

     # 数据删除方法
    def delete_data(self):
        session.delete(self)
        session.commit()


class Student(BaseModel):
    """
    学生表
    """
    __tablename__ = "student"
    name = db.Column(db.String(32))
    age = db.Column(db.Integer)
    gender = db.Column(db.String(32))
    to_attend = db.relationship(
        "Attend",
        backref = "to_student"
    )

# 学生课程关联表(多对多),也可以使用上面的方式创建该表
Student_Course = db.Table(
    "student_course",
    db.Column("id",db.Integer,primary_key=True,autoincrement=True),
    db.Column("student_id",db.Integer,db.ForeignKey("student.id")),
    db.Column("course_id",db.Integer,db.ForeignKey("course.id")),
    db.Column("delete_flag",db.Integer,default=1)  # 1没有停课 0停课

)

class Course(BaseModel):
    """
    课程表
    """
    __tablename__ = "course"
    name = db.Column(db.String(32))
    description = db.Column(db.Text)
    to_teacher = db.relationship(
        'Teacher', # 映射模型
        backref = 'to_course', # 反向映射字段,反向映射表通过该字段查询当前表
    ) # 映射表字段

    to_student = db.relationship(
        "Student",# 映射模型
        secondary = Student_Course, # 第二映射的模型
        backref = db.backref("to_course",lazy="dynamic"),
        lazy = "dynamic"
            # select 访问该字段时,加载所有的映射数据
            # joined 对关联的两个表student和student_course进行join查询
            # dynamic 访问该字段时,不加载数据
    )

class Grade(BaseModel):
    """
    成绩表
    学生、课程关联此表
    """
    __tablename__ = "grade"
    grade = db.Column(db.Float,default=0)
    student_id = db.Column(db.Integer,db.ForeignKey("student.id"))
    course_id = db.Column(db.Integer,db.ForeignKey("course.id"))

class Attend(BaseModel):
    """
    考勤表:记录学生出勤状况
    学生考勤:一对多
    """
    __tablename__ = "attend"
    att_time = db.Column(db.Date)
    status = db.Column(db.Integer,default=1) # 0 请假 ;1 正常出勤 ;2 迟到 ;3 早退 ;4 旷课
    student_id = db.Column(db.Integer,db.ForeignKey("student.id"))

class Teacher(BaseModel):
    """
    老师表
    老师与课程是多对一
    """
    __tablename__ = "teacher"
    name = db.Column(db.String(32))
    age = db.Column(db.Integer)
    gender = db.Column(db.String(32))
    course_id = db.Column(db.Integer,db.ForeignKey("course.id"))

再创建视图路由文件views.py
在这里插入图片描述

"""
视图和路由文件
"""
from flask import render_template
from FlaskDirectory.main import app
from FlaskDirectory.models import Student

@app.route("/student_list/")
def student_list():
    students = Student.query.all()
    return render_template("student_lists.html",**locals())

最后创建项目管理文件manage.py
在这里插入图片描述

"""
项目管理文件
"""

from FlaskDirectory.models import db
from FlaskDirectory.views import app

if __name__ == "__main__":
    db.create_all()
    app.run()

至此一个简单的结构化flask项目已经完成了。结构化及代码、包导入完成之后就可以进行简单的测试。
运行项目管理文件manage.py
启动该flask项目进行页面测试
在这里插入图片描述
访问页面路由127.0.0.1:5000/student_list/测试成功
在这里插入图片描述

flask配置优化:
如果Flask配置有十几条,那么我们也得需要一个一个的配置,就会很麻烦。所有Flask有三种配置方式
第一种:就是我们之前用过的使用app.config进行配置
但是这种配置简单,不利于大规模配置
在这里插入图片描述

第二种:使用python文件进行配置
当前配置是一种很官方的配置,但是不够灵活
创建配置文件settings.py

import os

DEBUG = True

BASE_DIR = os.path.abspath(os.path.dirname(__file__))

SQLALCHEMY_DATABASE_URI = "sqlite:///"+os.path.join(BASE_DIR,"Student.sqlite")
SQLALCHEMY_COMMIT_ON_TEARDOWN = True
SQLALCHEMY_TRACK_MODIFICATIONS = True

加载配置文件(main.py

app.config.from_pyfile("settings.py")

在这里插入图片描述
第三种:使用类进行配置
这种配置比较多,可以快速的切换不同模式的配置,调试,上线,开发
创建配置文件config.py

import os

BASE_DIR = os.path.abspath(os.path.dirname(__file__))

# 通用配置
class BaseConfig():
    SQLALCHEMY_COMMIT_ON_TEARDOWN = True
    SQLALCHEMY_TRACK_MODIFICATIONS = True

# 调试配置
class DebugConfig(BaseConfig):
    DEBUG = True
    SQLALCHEMY_DATABASE_URI = "sqlite:///" + os.path.join(BASE_DIR, "Student_test.sqlite")

# 上线配置
class OnlineConfig(BaseConfig):
    DEBUG = False
    SQLALCHEMY_DATABASE_URI = "sqlite:///" + os.path.join(BASE_DIR, "Student.sqlite")

加载类配置(main.py

app.config.from_object('config.DebugConfig')

在这里插入图片描述
最终的项目结构:
在这里插入图片描述

官方内置配置

配置 说明
DEBUG 启用/禁用调试模式
TESTING 启用/禁用测试模式
PROPAGATE_EXCEPTIONS 显式地允许或禁用异常的传播。如果没有设置或显式地设置为 None ,当 TESTING 或 DEBUG 为真时,这个值隐式地为 true.
PRESERVE_CONTEXT_ON_EXCEPTION 默认情况下,如果应用工作在调试模式,请求上下文不会在异常时出栈来允许调试器内省。 这可以通过这个键来禁用。你同样可以用这个设定来强制启用它,即使没有调试执行,这对调试生产应用很有用(但风险也很大)
SECRET_KEY 密钥
SESSION_COOKIE_NAME 会话 cookie 的名称。
SESSION_COOKIE_DOMAIN 会话 cookie 的域。如果不设置这个值,则 cookie 对 SERVER_NAME 的全部子域名有效
SESSION_COOKIE_PATH 会话 cookie 的路径。如果不设置这个值,且没有给 ‘/’ 设置过,则 cookie 对APPLICATION_ROOT 下的所有路径有效。
SESSION_COOKIE_HTTPONLY 控制 cookie 是否应被设置 httponly 的标志, 默认为 True
SESSION_COOKIE_SECURE 控制 cookie 是否应被设置安全标志,默认为 False
PERMANENT_SESSION_LIFETIME 以 datetime.timedelta 对象控制长期会话的生存时间。从 Flask 0.8 开始,也可以用整数来表示秒。
SESSION_REFRESH_EACH_REQUEST 这个标志控制永久会话如何刷新。如果被设置为True (这是默认值),每一个请求 cookie 都会被刷新。如果设置为 False ,只有当 cookie 被修改后才会发送一个 set-cookie 的标头。非永久会话不会受到这个配置项的影响 。
USE_X_SENDFILE 启用/禁用 x-sendfile
LOGGER_NAME 日志记录器的名称
SERVER_NAME 服务器名和端口。需要这个选项来支持子域名 (例如: ‘myapp.dev:5000’ )。注意 localhost 不支持子域名,所以把这个选项设置为 “localhost” 没有意义。设置 SERVER_NAME 默认会允许在没有请求上下文而仅有应用上下文时生成 URL
APPLICATION_ROOT 如果应用不占用完整的域名或子域名,这个选项可以被设置为应用所在的路径。这个路径也会用于会话 cookie 的路径值。如果直接使用域名,则留作 None
MAX_CONTENT_LENGTH 如果设置为字节数, Flask 会拒绝内容长度大于此值的请求进入,并返回一个 413 状态码
SEND_FILE_MAX_AGE_DEFAULT 默认缓存控制的最大期限,以秒计,在flask.Flask.send_static_file() (默认的静态文件处理器)中使用。对于单个文件分别在Flask 或 Blueprint 上使用get_send_file_max_age() 来覆盖这个值。默认为 43200(12小时)。
TRAP_HTTP_EXCEPTIONS 如果这个值被设置为 True ,Flask不会执行 HTTP 异常的错误处理,而是像对待其它异常一样, 通过异常栈让它冒泡地抛出。这对于需要找出 HTTP 异常源头的可怕调试情形是有用的。
TRAP_BAD_REQUEST_ERRORS Werkzeug 处理请求中的特定数据的内部数据结构会抛出同样也是“错误的请求”异常的特殊的 key errors 。同样地,为了保持一致,许多操作可以显式地抛出 BadRequest 异常。因为在调试中,你希望准确地找出异常的原因,这个设置用于在这些情形下调试。如果这个值被设置为 True ,你只会得到常规的回溯。
PREFERRED_URL_SCHEME 生成URL的时候如果没有可用的 URL 模式话将使用这个值。默认为 http
JSON_AS_ASCII 默认情况下 Flask 使用 ascii 编码来序列化对象。如果这个值被设置为 False , Flask不会将其编码为 ASCII,并且按原样输出,返回它的 unicode 字符串。比如 jsonfiy 会自动地采用utf-8 来编码它然后才进行传输。
JSON_SORT_KEYS 默认情况下 Flask 按照 JSON 对象的键的顺序来序来序列化它。这样做是为了确保键的顺序不会受到字典的哈希种子的影响,从而返回的值每次都是一致的,不会造成无用的额外 HTTP 缓存。你可以通过修改这个配置的值来覆盖默认的操作。但这是不被推荐的做法因为这个默认的行为可能会给你在性能的代价上带来改善。
JSONIFY_PRETTYPRINT_REGULAR 如果这个配置项被 True (默认值), 如果不是 XMLHttpRequest 请求的话(由 X-Requested-With 标头控制) json 字符串的返回值会被漂亮地打印出来。
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!