博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(旧) 1- 大家一起学:Flask构建弹幕微电影网站-(一)-(三)合集:数据模型设计映射成表...
阅读量:7241 次
发布时间:2019-06-29

本文共 17842 字,大约阅读时间需要 59 分钟。

Flask 构建微电影视频网站

已上线演示地址:

项目源码地址:

本节教程对应github : commit:1-3完结并将ip密码省去.

持续更新教程与代码commit。欢迎大家一起学习,star。

介绍微电影网站整体开发流程

flask:轻量级,冗余度小,扩展丰富,可以自由选择组合各种插件,性能优越。

前台加后台微电影网站.

系统介绍:

前台首页-电影筛选-电影列表- 播放详情-评论:收藏-搜索-注册-登录-会员中心(修改会员资料,查看评论记录,登录日志,收藏电影)

后台-标签-电影管理-预告-会员-评论-收藏-日志-权限管理-角色-管理员。

适合人群:pythoner

个人必备基础:

  • 有自学能力
  • 需要掌握python基本语法。
  • 会使用mysql数据库
  • 会linux基本操作
  • 有前端基础知识

课程介绍

flask + mysql

项目整体模块

开发及生产环境:

技术路线

国内知名的使用python做web开发。

国内python

python框架对比:

框架对比

flask简介

werkzeug封装了许多功能:文件上传。生成密码,校验密码等。

flask简介

微内核框架:

微内核框架

我们将学到得如下flask框架知识:

flask框架知识
flask框架知识2
flask框架知识3

微内核 + 丰富的扩展插件:

flask插件
flask插件
视频技术

环境搭建与工具

搭建开发环境安装依赖包,virtualenv虚拟化环境的使用

windows环境搭建:

  • windows10(or win7)
  • python3.6
  • mysql5.7
  • 虚拟化环境:virtualenv:pip install virtualenv
  • 代码编辑器:pycharm(社区版就足够)

pycharm编辑器使用,介绍pip下载工具使用

pycharm:新建文件->点击run运行

  1. virtualenv的使用及flask安装

virtualenv的使用:

  • 创建虚拟环境:virtualenv venv
  • 激活虚拟环境: source venv/bin/activate
  • 退出虚拟环境 :deactivate
  1. flask的安装:
  • 安装前检测:pip freeze
  • 安装flask: pip install flask
  • 安装后检测:pip freeze

error:

安装flask报错:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb6 in position 33: invalid
start byte

当前虚拟环境\lib\site-packages\pip\compat_init_.py约75行

return s.decode('utf_8') 改为return s.decode('cp936')

第一个flask程序

点击新建project->movie_project->选择解释环境为刚才新建的flask3

# _*_ coding: utf-8 _*___author__ = 'mtianyan'__date__ = '2017/8/26 16:56'from flask import Flaskapp = Flask(__name__)@app.route("/")def index():    return "

Hello World!

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

右键点击run之后:控制台画面如下:

控制台信息

点击链接可看到红色的helloworld,此时flask安装及运行成功。

项目优化与模型设计

前后台项目目录分析:

微电影网站:

  • 前台模块(home)
  • 后台模块(admin)

前台模块:

  • 数据模型:models.py
  • 表单处理: home/forms.py
  • 模板目录: templates/home
  • 静态目录:static

后台

  • 数据模型:models.py
  • 表单处理: admin/forms.py
  • 模板目录: templates/admin
  • 静态目录:static

前台后台表单处理,模板目录独立。数据模型共有。

前后台目录分析:

项目目录分析

pythonpackage:

  • app
  • app::admin
  • app::home

directory:

  • static
  • templates
  • templates::admin
  • templates::home

最终项目目录如下图:

目录结构

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

  1. 什么是蓝图?

一个应用中或跨应用制作应用组件和支持通用的模式

  1. 蓝图的作用:
  • 将不同的功能模块化
  • 构建大型应用
  • 优化项目结构
  • 增强可读性,易于维护

将项目合理规划,易于扩展。

  • 定义蓝图(app/admin/__init__.py)
from flask import Blueprintadmin = Blueprint("admin",__name__)import views
  • 注册蓝图(app/__init__.py)
from admin import admin as admin_blueprintapp.register_blueprint(admin_blueprint,url_prefix="admin")
  • 调用蓝图(app/admin/views.py)
from . import admin@admin.route("/")

实际编码:

home/init.py:

from . import home@home.route("/")def index():    return "

this is home

"

admin/init.py"

from flask import Blueprintadmin = Blueprint("admin",__name__)import app.admin.views
  • 第一步:定义出了两个蓝图对象。
  • 第二步:去views.py内调用蓝图对象:

home/views.py:

from . import home@home.route("/")def index():    return "

this is home

"

admin/views.py:

# _*_ coding: utf-8 _*___author__ = 'mtianyan'__date__ = '2017/8/26 17:06'from . import admin@admin.route("/")def index():    return "

this is admin

"
  • 第三步:要注册蓝图对象

app/init.py:

# _*_ coding: utf-8 _*___author__ = 'mtianyan'__date__ = '2017/8/26 17:05'from flask import Flaskapp = Flask(__name__)app.debug = Truefrom app.home import home as home_blueprintfrom app.admin import admin as admin_blueprintapp.register_blueprint(home_blueprint)app.register_blueprint(admin_blueprint, url_prefix="/admin")

并为admin设置了url前缀"/admin"

  • 最后一步:manage.py。启动app。

manage.py:

# _*_ coding: utf-8 _*___author__ = 'mtianyan'__date__ = '2017/8/26 17:05'from app import appif __name__ == "__main__":    app.run()

成果:

点击run之后可以在浏览器里看到:
前台绿色,后台(/admin)红色

使用flaskSQLAlchemy定义和业务需求相关的数据库模型

  • 安装数据库连接依赖包

    pip install flask-sqlalchemy:sqlalchemy(企业级的orm对象关系映射框架。面向对象的思想操作数据库)

  • 定义mysql数据库连接:

from flask_sqlalchemy import SQLAlchemyfrom flask import Flaskapp = from flask import Flask app = Flask(__name__)app.config['SQLALCHEMY_DATABASE_URL'] = "mysql://root:ty158917@localhost/movie"app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] =Truedb = SQLAlchemy(app)
  • 定义会员数据模型:
class User(db.Model):    __tablename__ = "user"    id = db.Column(db.Integer,primary_key=True)    name = db.Column(db.String)    pwd = db.Column(db.String)    email = db.Column(db.String)    phone = db.Column(db.String)    info = db.Column(db.Text)    face = db.Column(db.String)    addtime = db.Column(db.DateTime,index=True,default=datetime.utcnow)    uuid = db.Column(db.String)
会员数据模型字段说明
  • 会员登录日志数据模型:
    • id:编号
    • user_id:所属会员编号
    • ip:最近登录ip地址
    • addtime:最近登录时间

实际编码:

  • 控制台下使用:mysql -uroot -p密码进入mysql控制台
  • mysql>create database movie;来创建数据库

models.py:

# _*_ coding: utf-8 _*_import datetime__author__ = 'mtianyan'__date__ = '2017/8/26 17:05'from flask import Flaskfrom flask_sqlalchemy import SQLAlchemyapp = Flask(__name__)#用于连接数据的数据库。app.config['SQLALCHEMY_DATABASE_URL'] = "mysql://root:ty158917@127.0.0.1:3306/movie"#如果设置成 True (默认情况),Flask-SQLAlchemy 将会追踪对象的修改并且发送信号。app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] =Truedb = 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 '
' % 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 '
' % self.id

注意设置外键分为两步进行。

标签、电影、上映预告数据模型设计

  • 定义标签数据模型:
    • id:编号
    • name:标题
    • movies:电影外键关联
    • addtime:创建时间
  • 定义电影数据模型:
电影数据模型
  • 定义上映预告数据模型
    • id:编号
    • title:上映预告标题
    • logo:上映预告封面
    • addtime:创建时间
# 标签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 "
" % 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) # 播放量c 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') # 评论外键关系关联 moviecols = db.relationship("Moviecol", backref='movie') # 收藏外键关系关联 def __repr__(self): return "
" % 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 "
" % self.title

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

定义评论数据模型:

  • id:编号
  • content:评论内容
  • movie_id: 所属电影
  • user_id: 所属用户
  • addtime:最近登录时间
# 评论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 "
" % 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 "
" % self.id

权限及角色数据模型设计

定义权限数据模型:

  • id:编号
  • name:名称
  • url:地址(路由地址)
  • addtime:创建时间

定义角色模型:

  • id:编号
  • name:名称
  • auths:权限列表(多个权限以分隔符分开组成的字符串)
  • addtime:创建时间
  • admins:管理员外键关联
# 权限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.now)  # 添加时间    def __repr__(self):        return "
" % 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.now) # 添加时间 admins = db.relationship("Admin", backref='role') # 管理员外键关系关联 def __repr__(self): return "
" % 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.now)  # 添加时间    adminlogs = db.relationship("Adminlog", backref='admin')  # 管理员登录日志外键关系关联    oplogs = db.relationship("Oplog", backref='admin')  # 管理员操作日志外键关系关联    def __repr__(self):        return "
" % self.name def check_pwd(self, pwd): from werkzeug.security import check_password_hash return check_password_hash(self.pwd, pwd)# 管理员登录日志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.now) # 登录时间 def __repr__(self): return "
" % 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.now) # 登录时间 def __repr__(self): return "
" % self.id

结合mysql数据库生成数据表

  1. 安装pymysql然后点击run运行。

故障提示:

SQLAlchemy插入数据产生警告

cursors.py:166: Warning: (1366, "Incorrect string value: '\\xD6\\xD0\\xB9\\xFA\\xB1\\xEA...' for column 'VARIABLE_VALUE' at row 479")result = self._query(query)

windows系统默认使用的是gbk的字符集,而我在windows系统上使用的数据库也是在本机windows系统上,而报错是因为字符集的问题,但是我指定了数据库的字符集是utf8的,然每次连接依然有这个错误,个人分析应该是系统字符串造成的。所以我改到使用linux系统里的mysql建立一个utf8的数据库后,使用未出现上述问题,所以分析应该是系统字符串导致的。

此处我使用了远程连接linux服务器上的数据库,消除了警告。

完整models.py代码:

# _*_ coding: utf-8 _*_from datetime import datetime__author__ = 'mtianyan'__date__ = '2017/8/26 17:05'from flask import Flaskfrom flask_sqlalchemy import SQLAlchemyimport pymysqlapp = Flask(__name__)#用于连接数据的数据库。app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://用户名:密码@ip地址:3306/movie"#如果设置成 True (默认情况),Flask-SQLAlchemy 将会追踪对象的修改并且发送信号。app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] =Truedb = 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 '
' % 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 '
' % 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 "
" % 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) # 播放量c 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') # 评论外键关系关联 moviecols = db.relationship("Moviecol", backref='movie') # 收藏外键关系关联 def __repr__(self): return "
" % 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 "
" % 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 "
" % 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 "
" % 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.now) # 添加时间 def __repr__(self): return "
" % 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.now) # 添加时间 admins = db.relationship("Admin", backref='role') # 管理员外键关系关联 def __repr__(self): return "
" % 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.now) # 添加时间 adminlogs = db.relationship("Adminlog", backref='admin') # 管理员登录日志外键关系关联 oplogs = db.relationship("Oplog", backref='admin') # 管理员操作日志外键关系关联 def __repr__(self): return "
" % self.name def check_pwd(self, pwd): from werkzeug.security import check_password_hash return check_password_hash(self.pwd, pwd)# 管理员登录日志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.now) # 登录时间 def __repr__(self): return "
" % 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.now) # 登录时间 def __repr__(self): return "
" % self.idif __name__ == "__main__": db.create_all()

最终映射成功后的数据表:

运行成功
映射出的数据库表

附录:

mysql命令:

  • use movie;
  • show tables;
  • desc admin;

转载地址:http://ktfbm.baihongyu.com/

你可能感兴趣的文章
python中将图片从客户端(client)推到(POST)到服务器端(server)的方法
查看>>
落地生根两周年,微软Azure进入2.0时代
查看>>
一维maxpooling
查看>>
如何在Centos7上安装和使用ZFS
查看>>
ASCII
查看>>
poj2021
查看>>
mysql 直接从date 文件夹备份表,还原数据库之后提示 table doesn`t exist的原因和解决方法...
查看>>
poj3103
查看>>
HDU 4791 & ZOJ 3726 Alice's Print Service (数学 打表)
查看>>
01背包
查看>>
HttpClient4.X 升级 入门 + http连接池使用
查看>>
魅族MX3 smart bar处失灵
查看>>
一套简单可依赖的Javascript库
查看>>
MySQL对于datetime 源码分析
查看>>
Linux PAM&&PAM后门
查看>>
3 构建Mysql+heartbeat+DRBD+LVS集群应用系统系列之heartbeat的搭建
查看>>
第一百二十三节,JavaScript错误处理与调试
查看>>
WebAssembly,可以作为任何编程语言的编译目标,使应用程序可以运行在浏览器或其它代理中——浏览器里运行其他语言的程序?...
查看>>
【公告】博客数据异常已所有恢复
查看>>
JavaScript 刚開始学习的人应知的 24 条最佳实践
查看>>