美文网首页利用Flask搭建微电影视频网站Python
利用Flask搭建微电影视频网站(二):项目优化与模型设计

利用Flask搭建微电影视频网站(二):项目优化与模型设计

作者: 啃饼小白 | 来源:发表于2018-09-03 07:33 被阅读92次

    关于博主

    努力与运动兼备~~~有任何问题可以加我好友或者关注微信公众号,欢迎交流,我们一起进步!

                                          微信公众号:  啃饼思录
    
                                        QQ: 2810706745(啃饼小白)
    

    写在前面

    从本篇笔记开始,我们正式进入flask的编程世界,话不多说,我们先来创建我们的第一个flask程序,然后进行项目的优化以及模型设计。

    本篇笔记对应上传的仓库为:https://github.com/licheetools/movie对应第二篇。

    第一个flask程序

    打开pycharm按照图示创建flask项目:

    点击确定之后就成了这样:


    你会发现上面2个文件static和templates竟然都是空的,也就说只有movie.py文件才有,而且只有寥寥的7行代码。我给你看一下Django创建项目之后的页面:
    看到没有,flask的确是轻巧,巧到刚开始只有2个空文件和一个7行代码的py文件。而纵观Django,刚开始就有那些看不懂的而且代码挺多的py文件,所以还是那句话,学好flask需要花费一定的时间。我们继续回到flask页面:点击上面的运行按钮,提示你在浏览器输入:http://127.0.0.1:5000/,flask的默认端口号为5000,Django的端口号为8000,要注意区别!你会发现页面只有Hello World!这个单词而已!!!

    项目优化与模型设计

    我们这个微电影网站包括:前台模块(home)后台模块(admin)


    其中前台模块(home)包括:
    数据模型:models.py
    表单处理: home/forms.py
    模板目录: templates/home
    静态目录:static



    而后台模块(admin)也同样包括:
    数据模型:models.py
    表单处理: admin/forms.py
    模板目录: templates/admin
    静态目录:static


    数据模型是共用的,而表单提交和模板都是独立的,下面看一下前后台的目录分析:
    按照上述图片所示,新建文件树:

    使用flask的蓝图(Blueprint)来规划项目的结构

    1、什么是蓝图?
    它是一个应用中或跨应用制作应用组件和支持通用的模式。
    2、蓝图的作用?
    将不同的功能模块化;构建大型应用;优化项目结构;增强可读性,易于维护。


    下面我们将对上面的3个目录进行分开介绍,由于前后台的目录结构很类似,这里我以app/admin为例进行说明,大家跟紧我的节奏即可。
    1、定义蓝图(app/admin/--init--.py)
    from flask import Blueprint
    admin = Blueprint("admin", __name__)
    import app.admin.views
    

    2、注册蓝图(app/--init--.py)

    from flask import Flask
    
    app = Flask(__name__)
    app.debug = True
    
    from app.admin import admin as admin_blueprint
    
    app.register_blueprint(admin_blueprint, url_prefix="/admin")
    

    3、调用蓝图(app/admin/views.py)

    from . import admin
    
    
    @admin.route("/")
    def index():
        return "<h1 style='color:blue'>This is admin</h1>"
    

    而在app/home里面同样是这样的:
    1、定义蓝图(app/home/--init--.py)

    from flask import Blueprint
    home = Blueprint("home", __name__)
    import app.home.views
    

    2、注册蓝图(app/--init--.py)

    from flask import Flask
    
    app = Flask(__name__)
    app.debug = True
    
    from app.home import admin as home_blueprint
    
    app.register_blueprint(home_blueprint) # 这里url可以不写
    

    3、调用蓝图(app/home/views.py)

    from . import admin
    
    
    @home.route("/")
    def index():
        return "<h1 style='color:red'>This is home</h1>"
    

    在完成上述代码之后,最后一步书写manage.py文件,开始启动app。

    from app import app
    if __name__ == '__main__':
        app.run()
    

    在浏览器地址栏中输入:http://127.0.0.1:5000,则显示红色的This is home;而输入http://127.0.0.1:5000/admin/,则显示蓝色的This is admin.

    会员及会员登录日志数据模型设计

    1、安装数据库连接依赖包

    pip install flask-sqlalchemy -i https://pypi.tuna.tsinghua.edu.cn/simple
    

    关于sqlalchmey的介绍,请关注我的另外一个专题《Python3操作三大数据库》这里面就会有详细的介绍,这里我就不细说了,你只要记住它是一个企业级的ORM对象关系映射框架就够了。
    2、定义mysql数据库连接:
    打开models.py文件,我们新建下面的代码:

    from flask_sqlalchemy import SQLAlchemy
    from flask import Flask
    
    app = from flask import Flask 
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URL'] = "mysql://账号:密码@ip地址/movie"
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] =True
    db = SQLAlchemy(app)
    

    大家可以点击flask-sqlalchemy,来了解更多的信息。

    3、定义会员数据模型:

    继续在models.py文件里添加代码:

    # 定义会员数据模型
    class User(db.Model):
        __tablename__ = "user"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        name = db.Column(db.String(100), unique=True)  # 昵称
        pwd = db.Column(db.String(100))  # 密码
        email = db.Column(db.String(100), unique=True)  # 邮箱
        phone = db.Column(db.String(11), unique=True)  # 电话号码
        info = db.Column(db.Text)  # 个性简介
        face = db.Column(db.String(255), unique=True)  # 头像
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
        uuid = db.Column(db.String(255), unique=True)  # 唯一标志符
    
        def __repr__(self):
            return '<User %r>' % self.name
    

    大家对此内容不了解可以点击声明模型

    4、会员登录日志数据模型:

    # 会员登录日志
    class UserLog(db.Model):
        __tablename__ = "userlog"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        user_id = db.Column(db.Integer, db.ForeignKey('user.id'))  # 所属会员
        ip = db.Column(db.String(100))  # 登录IP
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
    
        def __repr__(self):
            return '<UserLog %r>' % self.id
    

    注意由于此处采用了外键,所以需要在User函数里面新增关系:

      userlogs = db.relationship('userlog', backref='user')  # 会员日志外键关系
    

    注意到没有,这里和Django中字段的定义是不一样的,Django不需要在关系外键里面增加外键关系,但是Flask却是必须的,要注意这一点。

    总结一下,models.py文件的代码为:

    
    from flask import Flask
    from flask_sqlalchemy import SQLAlchemy
    import datetime
    
    app = Flask(__name__)
    app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:root@127.0.0.5/movie"
    app.config["SQLALCHEMY_TRACK_MODIFICATIONS  "] = True
    db = SQLAlchemy(app)
    
    
    # 定义会员数据模型
    class User(db.Model):
        __tablename__ = "user"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        name = db.Column(db.String(100), unique=True)  # 昵称
        pwd = db.Column(db.String(100))  # 密码
        email = db.Column(db.String(100), unique=True)  # 邮箱
        phone = db.Column(db.String(11), unique=True)  # 电话号码
        info = db.Column(db.Text)  # 个性简介
        face = db.Column(db.String(255), unique=True)  # 头像
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
        uuid = db.Column(db.String(255), unique=True)  # 唯一标志符
        userlogs = db.relationship('UserLog', backref='user')  # 会员日志外键关系
    
        def __repr__(self):
            return '<User %r>' % self.name
    
    
    # 会员登录日志
    class UserLog(db.Model):
        __tablename__ = "userlog"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        user_id = db.Column(db.Integer, db.ForeignKey('user.id'))  # 所属会员
        ip = db.Column(db.String(100))  # 登录IP
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
    
        def __repr__(self):
            return '<UserLog %r>' % self.id
    
    

    5、标签数据模型设计

    # 定义标签数据模型
    class Tag(db.Model):
        __tablename__ = "tag"
        id = db.Column(db.Integer, primary_key=True)   # 编号
        name = db.Column(db.String(100), unique=True)   # 标题
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
        movies = db.relationship('Movie', backref='tag')  # 电影外键关系关联
    
        def __repr__(self):
            return '<Tag %r>' % self.name
    
    

    其中,relationship('Movie', backref='tag')里面,Movie为所关联的类名,backref为当前的表名!
    6、电影数据模型设计

    
    # 定义电影数据模型
    class Movie(db.Model):
        __tablename__ = "movie"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        title = db.Column(db.String(255), unique=True)  # 电影标题
        url = db.Column(db.String(255), unique=True)  # 电影地址
        info = db.Column(db.Text)  # 电影简介
        logo = db.Column(db.String(255), unique=True)  # 电影封面
        star = db.Column(db.SmallInteger)  # 星级
        playnum = db.Column(db.BigInteger)  # 电影播放量
        commentnum = db.Column(db.BigInteger)  # 电影播放量
        tag_id = db.Column(db.Integer, db.ForeignKey('tag.id'))  # 所属标签
        area = db.Column(db.String(255))  # 地区
        release_time = db.Column(db.Date)  # 发布时间
        length = db.Column(db.String(100))  # 电影长度
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
    
        def __repr__(self):
            return '<Movie %r>' % self.title
    

    7、上映预告数据模型设计

    # 定义上映预告数据模型
    class Preview(db.Model):
        __tablename__ = "preview"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        title = db.Column(db.String(255), unique=True)  # 电影标题
        logo = db.Column(db.String(255), unique=True)  # 电影封面
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
    
        def __repr__(self):
            return '<Preview %r>' % self.title
    

    评论及收藏电影数据模型设计

    1、定义评论数据模型:

    
    # 定义评论数据模型
    class Comment(db.Model):
        __tablename__ = "comment"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        content = db.Column(db.Text)  # 评论内容
        movie_id = db.Column(db.Integer, db.ForeignKey('movie.id'))  # 所属电影
        user_id = db.Column(db.Integer, db.ForeignKey('user.id'))  # 所属用户
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
    
        def __repr__(self):
            return '<Comment %r>' % self.id
    

    2、定义收藏电影数据模型:

    # 定义收藏电影数据模型
    class MovieCol(db.Model):
        __tablename__ = "moviecol"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        movie_id = db.Column(db.Integer, db.ForeignKey('movie.id'))  # 所属电影
        user_id = db.Column(db.Integer, db.ForeignKey('user.id'))  # 所属用户
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 最近登录时间
    
        def __repr__(self):
            return '<MovieCol %r>' % self.id
    

    权限及角色数据模型设计

    1、定义权限数据模型:

    # 定义权限数据模型
    class Auth(db.Model):
        __tablename__ = "auth"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        name = db.Column(db.String(100), unique=True)  # 名称
        url = db.Column(db.String(255), unique=True)  # 电影地址
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
    
        def __repr__(self):
            return '<Auth %r>' % self.name
    

    2、定义角色数据模型:

    # 定义角色数据模型
    class Role(db.Model):
        __tablename__ = "role"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        name = db.Column(db.String(100), unique=True)  # 名称
        auths = db.Column(db.String(600)) # 权限列表
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
    
        def __repr__(self):
            return '<Role %r>' % self.name
    

    管理员、管理员登陆日志、操作日志数据模型设计

    1、定义管理员数据模型

    # 定义管理员数据模型
    class Admin(db.Model):
        __tablename__ = "admin"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        name = db.Column(db.String(100), unique=True)  # 管理员名称
        pwd = db.Column(db.String(100))  # 管理员密码
        is_super = db.Column(db.SmallInteger)  # 是否为超级管理员,0为超级管理员
        role_id = db.Column(db.Integer, db.ForeignKey('role.id'))  # 所属角色
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
    
        def __repr__(self):
            return '<Admin %r>' % self.name
    

    2、定义管理员登陆日志数据模型

    # 定义管理员登陆日志数据模型
    class AdminLog(db.Model):
        __tablename__ = "adminlog"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        admin_id = db.Column(db.Integer, db.ForeignKey('admin.id'))  # 所属管理员
        ip = db.Column(db.String(100))  # 登录IP
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
    
        def __repr__(self):
            return '<AdminLog %r>' % self.id
    

    3、定义操作日志数据模型

    # 定义操作日志数据模型
    class OpLog(db.Model):
        __tablename__ = "oplog"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        admin_id = db.Column(db.Integer, db.ForeignKey('admin.id'))  # 所属管理员
        ip = db.Column(db.String(100))  # 登录IP
        reason = db.Column(db.String(600))  # 操作原因
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
    
        def __repr__(self):
            return '<OpLog %r>' % self.id
    

    考虑到部分关系只有全部字段定义完成以后才能开始,所以这里贴一下models.py的全部代码:

    #!/user/bin/python
    # -*- coding:utf-8 -*-
    # @Time: 2018/3/29 21:20
    # @Author: Envse
    # @File: models.py
    
    
    from flask import Flask
    from flask_sqlalchemy import SQLAlchemy
    from datetime import datetime
    
    app = Flask(__name__)
    app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://账号:密码@ip地址/movie"
    app.config["SQLALCHEMY_TRACK_MODIFICATIONS  "] = True
    db = SQLAlchemy(app)
    
    
    # 定义会员数据模型
    class User(db.Model):
        __tablename__ = "user"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        name = db.Column(db.String(100), unique=True)  # 昵称
        pwd = db.Column(db.String(100))  # 密码
        email = db.Column(db.String(100), unique=True)  # 邮箱
        phone = db.Column(db.String(11), unique=True)  # 电话号码
        info = db.Column(db.Text)  # 个性简介
        face = db.Column(db.String(255), unique=True)  # 头像
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
        uuid = db.Column(db.String(255), unique=True)  # 唯一标志符
        userlogs = db.relationship('UserLog', backref='user')  # 会员日志外键关系
        comments = db.relationship('Comment', backref='user')  # 评论外键关系关联
        moviecols = db.relationship('MovieCol', backref='user')  # 电影收藏外键关系关联
    
        def __repr__(self):
            return '<User %r>' % self.name
    
    
    # 定义会员登录日志模型
    class UserLog(db.Model):
        __tablename__ = "userlog"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        user_id = db.Column(db.Integer, db.ForeignKey('user.id'))  # 所属会员
        ip = db.Column(db.String(100))  # 登录IP
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
    
        def __repr__(self):
            return '<UserLog %r>' % self.id
    
    
    # 定义标签数据模型
    class Tag(db.Model):
        __tablename__ = "tag"
        id = db.Column(db.Integer, primary_key=True)   # 编号
        name = db.Column(db.String(100), unique=True)   # 标题
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
        movies = db.relationship('Movie', backref='tag')  # 电影外键关系关联
    
        def __repr__(self):
            return '<Tag %r>' % self.name
    
    
    # 定义电影数据模型
    class Movie(db.Model):
        __tablename__ = "movie"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        title = db.Column(db.String(255), unique=True)  # 电影标题
        url = db.Column(db.String(255), unique=True)  # 电影地址
        info = db.Column(db.Text)  # 电影简介
        logo = db.Column(db.String(255), unique=True)  # 电影封面
        star = db.Column(db.SmallInteger)  # 星级
        playnum = db.Column(db.BigInteger)  # 电影播放量
        commentnum = db.Column(db.BigInteger)  # 电影播放量
        tag_id = db.Column(db.Integer, db.ForeignKey('tag.id'))  # 所属标签
        area = db.Column(db.String(255))  # 地区
        release_time = db.Column(db.Date)  # 发布时间
        length = db.Column(db.String(100))  # 电影长度
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
        comments = db.relationship('Comment', backref='movie')  # 电影评论外键关联
        movieclos = db.relationship('MovieCol', backref='movie')  # 电影收藏外键关联
    
        def __repr__(self):
            return '<Movie %r>' % self.title
    
    
    # 定义上映预告数据模型
    class Preview(db.Model):
        __tablename__ = "preview"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        title = db.Column(db.String(255), unique=True)  # 电影标题
        logo = db.Column(db.String(255), unique=True)  # 电影封面
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
    
        def __repr__(self):
            return '<Preview %r>' % self.title
    
    
    # 定义评论数据模型
    class Comment(db.Model):
        __tablename__ = "comment"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        content = db.Column(db.Text)  # 评论内容
        movie_id = db.Column(db.Integer, db.ForeignKey('movie.id'))  # 所属电影
        user_id = db.Column(db.Integer, db.ForeignKey('user.id'))  # 所属用户
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
    
        def __repr__(self):
            return '<Comment %r>' % self.id
    
    
    # 定义收藏电影数据模型
    class MovieCol(db.Model):
        __tablename__ = "moviecol"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        movie_id = db.Column(db.Integer, db.ForeignKey('movie.id'))  # 所属电影
        user_id = db.Column(db.Integer, db.ForeignKey('user.id'))  # 所属用户
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 最近登录时间
    
        def __repr__(self):
            return '<MovieCol %r>' % self.id
    
    
    # 定义权限数据模型
    class Auth(db.Model):
        __tablename__ = "auth"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        name = db.Column(db.String(100), unique=True)  # 名称
        url = db.Column(db.String(255), unique=True)  # 电影地址
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
    
        def __repr__(self):
            return '<Auth %r>' % self.name
    
    
    # 定义角色数据模型
    class Role(db.Model):
        __tablename__ = "role"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        name = db.Column(db.String(100), unique=True)  # 名称
        auths = db.Column(db.String(600)) # 权限列表
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
    
        def __repr__(self):
            return '<Role %r>' % self.name
    
    
    # 定义管理员数据模型
    class Admin(db.Model):
        __tablename__ = "admin"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        name = db.Column(db.String(100), unique=True)  # 管理员名称
        pwd = db.Column(db.String(100))  # 管理员密码
        is_super = db.Column(db.SmallInteger)  # 是否为超级管理员,0为超级管理员
        role_id = db.Column(db.Integer, db.ForeignKey('role.id'))  # 所属角色
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
        adminlogs = db.relationship('AdminLog', backref='admin')  # 管理员登录日志外键关系关联
        oplogs = db.relationship('OpLog', backref='admin')  # 管理员操作日志外键关系关联
    
        def __repr__(self):
            return '<Admin %r>' % self.name
    
    
    # 定义管理员登陆日志数据模型
    class AdminLog(db.Model):
        __tablename__ = "adminlog"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        admin_id = db.Column(db.Integer, db.ForeignKey('admin.id'))  # 所属管理员
        ip = db.Column(db.String(100))  # 登录IP
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
    
        def __repr__(self):
            return '<AdminLog %r>' % self.id
    
    
    # 定义操作日志数据模型
    class OpLog(db.Model):
        __tablename__ = "oplog"
        id = db.Column(db.Integer, primary_key=True)  # 编号
        admin_id = db.Column(db.Integer, db.ForeignKey('admin.id'))  # 所属管理员
        ip = db.Column(db.String(100))  # 登录IP
        reason = db.Column(db.String(600))  # 操作原因
        addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow)  # 添加时间
    
        def __repr__(self):
            return '<OpLog %r>' % self.id
    
    if __name__ == '__main__':
        db.create_all()  # 开始创建数据表
    

    结合mysql数据库来生成数据表

    1、进入到虚拟环境后,安装pymysql

    pip install pymysql -i https://pypi.tuna.tsinghua.edu.cn/simple
    

    2、导入pymysql并加以使用

    import pymysql
    app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://账号:密码@ip地址/movie"
    

    3、运行models.py文件
    运行models.py文件之后,你会发现出现字符编码的问题:

    F:\Envs\movie\lib\site-packages\pymysql\cursors.py:170: Warning: (1366, "Incorrect string value: '\\xD6\\xD0\\xB9\\xFA\\xB1\\xEA...' for column 'VARIABLE_VALUE' at row 481")
    

    因为windows系统默认使用的是GBK字符集,而我们在windows系统上使用的数据库默认也是GBK字符集,尽管我们在创建数据库的时候已经把字符集设定为utf8,但还是有问题,说明还是系统字符集影响到了我们项目的运行。但是数据库定义没问题,你输入中文是没有问题的这是mysql5.7的一个Bug,你可以忽略这个问题。

    博主通过各方努力终于找到了解决问题的办法:Flask利用pymysql出现Warning:1366的解决办法

    4、打开movie数据库
    打开数据库,你会发现新生成了许多数据表,这与我们在models.py文件里定义的一模一样。

    至此本篇关于项目优化与模型设计的介绍就到此为止了,感谢你的赏阅!

    本篇笔记对应上传的仓库为:https://github.com/licheetools/movie对应第二篇。

    相关文章

      网友评论

        本文标题:利用Flask搭建微电影视频网站(二):项目优化与模型设计

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