“轻”是Flask的精髓,小型项目快速开发,大型项目毫无压力
- 1-1 课程导学及介绍
- 1-2 Windows环境搭建
- 2-2 Mac OS环境搭建
- 2-3 第一Flask程序
- 3-1 项目分析及会员登录
- 3-2 标签-电影-上映预告数据模型设计
- 3-3 评论-收藏-权限-管理员-操作日志数据模型设计
- 4-1 前台布局-会员登录页面搭建
- 4-2 会员注册-会员中心页面搭建
- 4-3 电影列表-搜索页面搭建
- 4-4 电影详情页-404页面搭建
- 5-1 管理员登录-后台布局搭建
- 5-2 修改密码-控制面板-标签管理页面搭建
- 5-3 电影管理-上映预告管理页面搭建
- 5-4 会员-收藏-评论管理页面搭建
- 5-5 收藏-日志-角色管理页面搭建
- 5-6 管理员页面搭建
- 6-1 管理员登录
- 6-2 标签管理
- 6-3 电影管理-添加电影
- 6-4 电影管理-列表、删除、编辑
- 6-5 预告管理
- 6-6 会员管理
- 6-7 评论-收藏管理
- 6-8 修改密码
- 6-9 日志管理
- 7-1 权限管理
- 7-2 角色管理
- 7-3 管理员管理
- 7-4 访问权限控制
- 8-1 会员注册
- 8-2 会员登录
- 8-3 修改会员资料
- 8-4 修改密码
- 8-5 会员登录日志
- 9-1 上映预告-标签筛选-电影分页
- 9-2 电影搜索-电影详情
- 10-1 电影评论-统计
- 10-2 收藏电影
- 10-3 电影弹幕-代码优化及Bug处理
- 11-1 CentOS安装LNMP
- 11-2 部署电影网站-流媒体访问限制
1-1 课程导学及介绍
-
学会使用整型、浮点型、路径型、字符串型正则表达式路由转化器;
-
学会使用post与get请求、上传文件、cookie获取与响应、404处理;
-
学会使用模板自动转义、定义过滤器、定义全局上下文处理器、Jinja2语法、包含、继承、定义宏;
-
学会使用Flask-wtf定义表单模型、字段类型、字段验证、视图处理表单、模板使用表单;
-
学会使用flask-SQLAlchemy定义数据库模型、添加数据、修改数据、查询数据、删除数据、数据库事件、数据迁移;
-
学会使用蓝图优化项目结构、实现微电影网站前后台业务逻辑;
-
学会flask的部署方法、安装编译Nginx服务、安装编译Python3.6服务、安装MySQL服务以及通过Nginx反向代理对视频流媒体限制下载速率、限制单个IP能发起的播放连接数;
























1-2 Windows环境搭建
1.2.1 操作系统:Win7;
1.2.2 编程语言:Python3.6;
1.2.3 数据库:MySQL5.7;
1.2.4 虚拟化开发环境:virtualenv;
1.2.5 IDE:Pycharm;
使用豆瓣源安装pip install ,国内镜像地址,速度会快很多。用法:pip install -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com flask

2-2 MacOS环境搭建
2.2.1 Python3.6;
2.2.2 Pycharm2018.3;
2.2.3 MySQL8.0.12;
2.2.4 注意pip install flask 以及pip3 install flask的区别;
2-3 第一Flask程序
2.3.1 virtualenv的使用;
- virtualenv venv
2.3.2 flask的安装;
- pip3 install flask
- pip3 freeze
- deactivate # 退出虚拟化环境

2.2.3 第一个flask程序的编写;
-
安装flask==“0.12.2”
#!/usr/bin/python3
-- coding:utf-8 --
Project: MicroFilm
Software: PyCharm
Time : 2018-09-28 16:29
File : app.py
Author : 天晴天朗
Email : tqtl@tqtl.org
from flask import Flask
app = Flask(name)
@app.route("/") def index(): return "<h1 style = 'color:red'>Hello Flask!</h1>"
if name == 'main': app.run()





3-1 项目分析及会员登录
3.1.1 项目分析、搭建目录及模型设计;




3.1.2 前后目录结构分析;


3.1.3 使用蓝图(蓝本Blueprint)来构建项目目录;
1)什么是蓝图?
- 一个应用中或跨应用制作应用组件和支持通用的模式;
2)蓝图的作用?
- 将不同的功能模块化;
- 构建大型应用;
- 优化项目结构;
- 增强可读性、易于维护;
3.1.4 蓝图的使用步骤:
- 定义蓝图;
- 注册蓝图;
- 调用蓝图;



3.1.5 会员及会员登录日志数据模型设计;
1)安装数据库连接工具flask-SQLAlchemy(企业级Python的ORM对象关系映射框架,面向对象的思想);
2)定义MySQL数据库连接基于pymysql+ mysql;
3)pip3 install flask-sqlalchemy的安装;

3.1.5 定义数据模型;
- pip3 install flask-sqlalchemy;



3.1.6 配置SQLAlchemy;
SQLAlchemy在线文档:http://www.pythondoc.com/flask-sqlalchemy/config.html
app/models.py的设计;
1#!/usr/bin/python3 2# -*- coding:utf-8 -*- 3# Project: MicroFilm 4# Software: PyCharm 5# Time : 2018-09-28 16:36 6# File : models.py 7# Author : 天晴天朗 8# Email : tqtl@tqtl.org 9from flask import Flask 10from flask_sqlalchemy import SQLAlchemy 11import datetime 12 13app = Flask(__name__) 14app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:Tqtl911!@#)^@localhost:3306/MicroFilm/" 15app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True 16 17db = SQLAlchemy(app) 18 19 20class User(db.Model): 21 """ 22 会员表; 23 """ 24 __tablename__ = "user" # 表名 25 id = db.Column(db.Integer, primary_key=True) # 编号 26 name = db.Column(db.String(100), unique=True) # 昵称 27 pwd = db.Column(db.String(100), unique=True) # 密码 28 email = db.Column(db.String(100), unique=True) # 邮箱 29 phone = db.Column(db.String(11), unique=True) # 手机号码 30 info = db.Column(db.Text) # 个性简介 31 face = db.Column(db.String(255), unique=True) # 头像 32 addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow) # 注册时间 33 uuid = db.Column(db.String(255), unique=True) # 唯一标识符 34 userlogs = db.relationship("UserLog", backref="user") # 外键关系的关联 35 36 def __repr__(self): 37 return "<User %r>" % self.name 38 39 40class UserLog(db.Model): 41 """ 42 会员登录日志表 43 """ 44 __tablename__ = "userlog" # 表名 45 id = db.Column(db.Integer, primary_key=True) # 编号 46 user_id = db.Column(db.Integer, db.ForeignKey('user.id')) # 所属会员 47 ip = db.Column(db.String(100)) # 登录IP 48 addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow) # 登录时间; 49 50 def __repr__(self): 51 return "<UserLog %r>" % self.id
3-2 标签-电影-上映预告数据模型设计
3.2.1 标签数据模型的设计;
3.2.2 电影数据模型设计;
3.2.3 上映预告数据模型的设计;
app/models.py;
1#!/usr/bin/python3 2# -*- coding:utf-8 -*- 3# Project: MicroFilm 4# Software: PyCharm 5# Time : 2018-09-28 16:36 6# File : models.py 7# Author : 天晴天朗 8# Email : tqtl@tqtl.org 9from flask import Flask 10from flask_sqlalchemy import SQLAlchemy 11from datetime import datetime 12 13app = Flask(__name__) 14app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:Tqtl911!@#)^@localhost:3306/MicroFilm/" 15app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True 16 17db = SQLAlchemy(app) 18 19 20class User(db.Model): 21 """ 22 会员表; 23 """ 24 __tablename__ = "user" # 表名 25 id = db.Column(db.Integer, primary_key=True) # 编号 26 name = db.Column(db.String(100), unique=True) # 昵称 27 pwd = db.Column(db.String(100), unique=True) # 密码 28 email = db.Column(db.String(100), unique=True) # 邮箱 29 phone = db.Column(db.String(11), unique=True) # 手机号码 30 info = db.Column(db.Text) # 个性简介 31 face = db.Column(db.String(255), unique=True) # 头像 32 addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow) # 注册时间 33 uuid = db.Column(db.String(255), unique=True) # 唯一标识符 34 userlogs = db.relationship("UserLog", backref="user") # 外键关系的关联 35 36 def __repr__(self): 37 return "<User %r>" % self.name 38 39 40class UserLog(db.Model): 41 """ 42 会员登录日志表 43 """ 44 __tablename__ = "userlog" # 表名 45 id = db.Column(db.Integer, primary_key=True) # 编号 46 user_id = db.Column(db.Integer, db.ForeignKey('user.id')) # 所属会员 47 ip = db.Column(db.String(100)) # 登录IP 48 addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow) # 登录时间; 49 50 def __repr__(self): 51 return "<UserLog %r>" % self.id 52 53 54class Tag(db.Model): 55 """ 56 标签 57 """ 58 __tablename__ = "tag" 59 id = db.Column(db.Integer, primary_key=True) # 编号 60 name = db.Column(db.String(100), unique=True) # 标题 61 addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow) # 添加时间 62 movies = db.relationship("Movie", backref="tag") # 电影外键关系的关联 63 64 def __repr__(self): 65 return "<Tag %r>" % self.name 66 67 68class Movie(db.Model): 69 """ 70 电影表 71 """ 72 __tablename__ = "movie" 73 id = db.Column(db.Integer, primary_key=True) # 编号 74 title = db.Column(db.String(255), unique=True) # 标题 75 url = db.Column(db.String(255), unique=True) # 地址 76 info = db.Column(db.Text) # 简介 77 logo = db.Column(db.String(255), unique=True) # 封面 78 star = db.Column(db.SmallInteger) # 星级 79 playnum = db.Column(db.BigInteger) # 播放量 80 commentnum = db.Column(db.BigInteger) # 评论量 81 tag_id = db.Column(db.Integer, db.ForeignKey("tag.id")) # 所属标签 82 area = db.Column(db.String(255)) # 上映地区 83 release_time = db.Column(db.Date) # 上映时间 84 length = db.Column(db.String(100)) # 播放时间 85 addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow) # 添加时间 86 87 def __repr__(self): 88 return "<Movie %r>" % self.title 89 90 91class Preview(db.Model): 92 """ 93 上映预告表 94 """ 95 __tablename__ = "preview" # 表名 96 id = db.Column(db.Integer, primary_key=True) # 编号 97 title = db.Column(db.String(255), unique=True) # 标题 98 logo = db.Column(db.String(255), unique=True) # 封面 99 addtime = db.Column(db.DateTime, index=True, default=datetime.utcnow) # 添加时间 100 101 def __repr__(self): 102 return "<Preview %r>" % self.title



3-3 评论-收藏-权限-管理员-操作日志数据模型设计
3.3.1 定义评论数据模型;
3.3.2 定义收藏电影数据模型;
3.3.3 定义权限数据模型;
3.3.4 定义角色数据模型;




3.3.5 定义管理员数据模型;
3.3.6 定义登录日志操作数据模型;
3.3.7 定义操作日志数据模型;


3.3.8 ModuleNotFoundError: No module named 'MySQLdb'报错处理之pip3 install pymysql;

3.3.9 执行python3 models.py 进行生成数据表操作;








app/models.py;
1#!/usr/bin/python3 2# -*- coding:utf-8 -*- 3# Project: MicroFilm 4# Software: PyCharm 5# Time : 2018-09-28 16:36 6# File : models.py 7# Author : 天晴天朗 8# Email : tqtl@tqtl.org 9from flask import Flask 10from flask_sqlalchemy import SQLAlchemy 11from datetime import datetime 12import pymysql 13 14app = Flask(__name__) 15app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:Tqtl911!@#)^@localhost:3306/MicroFilm" 16app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True 17 18db = SQLAlchemy(app) 19 20 21class User(db.Model): 22 """ 23 会员表; 24 """ 25 __tablename__ = "user" # 表名 26 id = db.Column(db.Integer, primary_key=True) # 编号 27 name = db.Column(db.String(100), unique=True) # 昵称 28 pwd = db.Column(db.String(100), unique=True) # 密码 29 email = db.Column(db.String(100), unique=True) # 邮箱 30 phone = db.Column(db.String(11), unique=True) # 手机号码 31 info = db.Column(db.Text) # 个性简介 32 face = db.Column(db.String(255), unique=True) # 头像 33 addtime = db.Column(db.DateTime, index=True, default=datetime.now) # 注册时间 34 uuid = db.Column(db.String(255), unique=True) # 唯一标识符 35 userlogs = db.relationship("UserLog", backref="user") # 会员日志外键关联 36 comments = db.relationship("Comment", backref="user") # 评论外键关联 37 moviecols = db.relationship("MovieCol", backref="user") # 收藏外键关联 38 39 def __repr__(self): 40 return "<User %r>" % self.name 41 42 43class UserLog(db.Model): 44 """ 45 会员登录日志表; 46 """ 47 __tablename__ = "userlog" # 表名 48 id = db.Column(db.Integer, primary_key=True) # 编号 49 user_id = db.Column(db.Integer, db.ForeignKey('user.id')) # 所属会员 50 ip = db.Column(db.String(100)) # 登录IP 51 addtime = db.Column(db.DateTime, index=True, default=datetime.now) # 登录时间; 52 53 def __repr__(self): 54 return "<UserLog %r>" % self.id 55 56 57class Tag(db.Model): 58 """ 59 标签表; 60 """ 61 __tablename__ = "tag" 62 id = db.Column(db.Integer, primary_key=True) # 编号 63 name = db.Column(db.String(100), unique=True) # 标题 64 addtime = db.Column(db.DateTime, index=True, default=datetime.now) # 添加时间 65 movies = db.relationship("Movie", backref="tag") # 电影外键关系的关联 66 67 def __repr__(self): 68 return "<Tag %r>" % self.name 69 70 71class Movie(db.Model): 72 """ 73 电影表; 74 """ 75 __tablename__ = "movie" 76 id = db.Column(db.Integer, primary_key=True) # 编号 77 title = db.Column(db.String(255), unique=True) # 标题 78 url = db.Column(db.String(255), unique=True) # 地址 79 info = db.Column(db.Text) # 简介 80 logo = db.Column(db.String(255), unique=True) # 封面 81 star = db.Column(db.SmallInteger) # 星级 82 playnum = db.Column(db.BigInteger) # 播放量 83 commentnum = db.Column(db.BigInteger) # 评论量 84 tag_id = db.Column(db.Integer, db.ForeignKey("tag.id")) # 所属标签 85 area = db.Column(db.String(255)) # 上映地区 86 release_time = db.Column(db.Date) # 上映时间 87 length = db.Column(db.String(100)) # 播放时间 88 addtime = db.Column(db.DateTime, index=True, default=datetime.now) # 添加时间 89 comments = db.relationship("Comment", backref="movie") # 评论外键关系关联 90 moviecols = db.relationship("MovieCol", backref="movie") # 收藏外键关系关联 91 92 def __repr__(self): 93 return "<Movie %r>" % self.title 94 95 96class Preview(db.Model): 97 """ 98 上映预告表; 99 """ 100 __tablename__ = "preview" # 表名 101 id = db.Column(db.Integer, primary_key=True) # 编号 102 title = db.Column(db.String(255), unique=True) # 标题 103 logo = db.Column(db.String(255), unique=True) # 封面 104 addtime = db.Column(db.DateTime, index=True, default=datetime.now) # 添加时间 105 106 def __repr__(self): 107 return "<Preview %r>" % self.title 108 109 110class Comment(db.Model): 111 """ 112 评论表; 113 """ 114 __tablename__ = "comment" 115 id = db.Column(db.Integer, primary_key=True) # 编号 116 content = db.Column(db.Text) # 内容 117 movie_id = db.Column(db.Integer, db.ForeignKey("movie.id")) # 所属电影 118 user_id = db.Column(db.Integer, db.ForeignKey("user.id")) # 所属用户 119 addtime = db.Column(db.DateTime, index=True, default=datetime.now) # 添加时间 120 121 def __repr__(self): 122 return "<Comment %r>" % self.id 123 124 125class MovieCol(db.Model): 126 """ 127 电影收藏表; 128 """ 129 __tablename__ = "moviecol" 130 id = db.Column(db.Integer, primary_key=True) # 编号 131 movie_id = db.Column(db.Integer, db.ForeignKey("movie.id")) # 所属电影 132 user_id = db.Column(db.Integer, db.ForeignKey("user.id")) # 所属用户 133 addtime = db.Column(db.DateTime, index=True, default=datetime.now) # 添加时间 134 135 def __repr__(self): 136 return "<MovieCol %4>" % self.id 137 138 139class Auth(db.Model): 140 """ 141 权限表; 142 """ 143 __tablename__ = "auth" 144 id = db.Column(db.Integer, primary_key=True) 145 name = db.Column(db.String(100), unique=True) 146 url = db.Column(db.String(255), unique=True) 147 addtime = db.Column(db.DateTime, index=True, default=datetime.now) 148 149 def __repr__(self): 150 return "<Auth %r>" % self.name 151 152 153class Role(db.Model): 154 """ 155 角色表; 156 """ 157 __tablename__ = "role" 158 id = db.Column(db.Integer, primary_key=True) # 编号 159 name = db.Column(db.String(100), unique=True) # 名称 160 auths = db.Column(db.String(600)) # 权限 161 addtime = db.Column(db.DateTime, index=True, default=datetime.now) # 添加时间 162 163 def __repr__(self): 164 return "<Role %r>" % self.name 165 166 167class Admin(db.Model): 168 """ 169 管理员表; 170 """ 171 __tablename__ = "admin" # 表名 172 id = db.Column(db.Integer, primary_key=True) # 编号 173 name = db.Column(db.String(100), unique=True) # 昵称 174 pwd = db.Column(db.String(100), unique=True) # 密码 175 is_super = db.Column(db.SmallInteger) # 是否为超级管理员,0为超级管理员; 176 role_id = db.Column(db.Integer, db.ForeignKey("role.id")) # 所属角色 177 addtime = db.Column(db.DateTime, index=True, default=datetime.now) # 添加时间 178 adminlogs = db.relationship("AdminLog", backref="admin") # 管理员登录日志 179 oplogs = db.relationship("OpLog", backref="admin") # 操作日志 180 181 def __repr__(self): 182 return "<Admin %r>" % self.name 183 184 185class AdminLog(db.Model): 186 """ 187 管理员登录日志表; 188 """ 189 __tablename__ = "adminlog" 190 id = db.Column(db.Integer, primary_key=True) 191 admin_id = db.Column(db.Integer, db.ForeignKey("admin.id")) 192 ip = db.Column(db.String(100)) 193 addtime = db.Column(db.DateTime, index=True, default=datetime.now) 194 195 def __repr__(self): 196 return "<AdminLog %r>" % self.id 197 198 199class OpLog(db.Model): 200 """ 201 操作日志表; 202 """ 203 __tablename__ = "oplog" 204 id = db.Column(db.Integer, primary_key=True) # 编号 205 admin_id = db.Column(db.Integer, db.ForeignKey("admin.id")) # 所属管理员 206 ip = db.Column(db.String(100)) # 登录IP 207 reason = db.Column(db.String(600)) # 操作原因 208 addtime = db.Column(db.DateTime, index=True, default=datetime.now) # 创建时间; 209 210 def __repr__(self): 211 return "<OpLog %r>" % self.id 212 213 214if __name__ == '__main__': 215 """ 216 db.create_all() 217 role = Role( 218 name="超级管理员", 219 auths="", 220 ) 221 db.session.add(role) 222 db.session.commit() 223 """ 224 from werkzeug.security import generate_password_hash 225 226 admin = Admin( 227 name="ImoocMovie1", 228 pwd=generate_password_hash("ImoocMovie1"), 229 is_super=0, 230 role_id=1 231 ) 232 db.session.add(admin) 233 db.session.commit()
4-1 前台布局-会员登录页面搭建
4.1.1 拷贝前端同事分享的static下的目录文件;


4.1.2 templates新增index.html、home.html;
4.1.3 报错待处理block 后面添加content对象;
index.html;
1{% extends "home/home.html" %} 2 3{% block content %} 4<h1>Hello Flask!!!</h1> 5{% endblock %}
home.html;
1<!doctype html> 2<html lang="zh-CN"> 3<head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="renderer" content="webkit"> 7 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 8 <meta name="viewport" content="width=device-width, initial-scale=1 , user-scalable=no"> 9 <title>微电影</title> 10 <link rel="shortcut icon" href="{{ url_for('static',filename ='base/images/logo.png') }}"> 11 <link rel="stylesheet" href="{{ url_for('static',filename ='base/css/bootstrap.min.css') }}"> 12 <link rel="stylesheet" href="{{ url_for('static',filename ='base/css/bootstrap-movie.css') }}"> 13 <link rel="stylesheet" href="{{ url_for('static',filename ='base/css/animate.css') }}"> 14 <style> 15 .navbar-brand > img { 16 display: inline; 17 } 18 19 </style> 20 <style> 21 .media { 22 padding: 3px; 23 border: 1px solid #ccc 24 } 25 26 </style> 27</head> 28 29<body> 30<!--导航--> 31<nav class="navbar navbar-default navbar-fixed-top"> 32 <div class="container"> 33 <!--小屏幕导航按钮和logo--> 34 <div class="navbar-header"> 35 <button class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> 36 <span class="icon-bar"></span> 37 <span class="icon-bar"></span> 38 <span class="icon-bar"></span> 39 </button> 40 <a href="index.html" class="navbar-brand" style="width:250px;"> 41 <img src="{{ url_for('static',filename = 'base/images/logo.png') }}" style="height:30px;"> 微电影 42 43 </a> 44 </div> 45 <!--小屏幕导航按钮和logo--> 46 <!--导航--> 47 <div class="navbar-collapse collapse"> 48 <form class="navbar-form navbar-left" role="search" style="margin-top:18px;"> 49 <div class="form-group input-group"> 50 <input type="text" class="form-control" placeholder="请输入电影名!"> 51 <span class="input-group-btn"> 52 <a class="btn btn-default" href="search.html"><span class="glyphicon glyphicon-search"></span> 搜索</a> 53 </span> 54 </div> 55 </form> 56 <ul class="nav navbar-nav navbar-right"> 57 <li> 58 <a class="curlink" href="index.html"><span class="glyphicon glyphicon-film"></span> 电影</a> 59 </li> 60 <li> 61 <a class="curlink" href="login.html"><span class="glyphicon glyphicon-log-in"></span> 登录</a> 62 </li> 63 <li> 64 <a class="curlink" href="register.html"><span class="glyphicon glyphicon-plus"></span> 注册</a> 65 </li> 66 <li> 67 <a class="curlink" href="logout.html"><span class="glyphicon glyphicon-log-out"></span> 退出</a> 68 </li> 69 <li> 70 <a class="curlink" href="user.html"><span class="glyphicon glyphicon-user"></span> 会员</a> 71 </li> 72 </ul> 73 </div> 74 <!--导航--> 75 76 </div> 77</nav> 78<!--导航--> 79<!--内容--> 80<div class="container" style="margin-top:76px"> 81 {% block content %}{% endblock %} 82</div> 83<!--内容--> 84<!--底部--> 85<footer> 86 <div class="container"> 87 <div class="row"> 88 <div class="col-md-12"> 89 <p> 90 © 2018 microfilm.cuixiaozhao.com 京ICP备 13046642号-2 91 </p> 92 </div> 93 </div> 94 </div> 95</footer> 96<!--底部--> 97<script src="{{ url_for('static',filename = 'base/js/jquery.min.js') }}"></script> 98<script src="{{ url_for('static',filename = 'base/js/bootstrap.min.js') }}"></script> 99<script src="{{ url_for('static',filename = 'base/js/jquery.singlePageNav.min.js') }}"></script> 100<script src="{{ url_for('static',filename = 'base/js/wow.min.js') }}"></script> 101<script src="{{ url_for('static',filename = 'lazyload/jquery.lazyload.min.js') }}"></script> 102<script src="//cdn.bootcss.com/holder/2.9.4/holder.min.js"></script> 103<script> 104 $(function () { 105 new WOW().init(); 106 }) 107 108</script> 109<script> 110 $(document).ready(function () { 111 $("img.lazy").lazyload({ 112 effect: "fadeIn" 113 }); 114 }); 115</script> 116</body> 117</html>
4.1.4 页面呈现;


4-2 会员注册-会员中心页面搭建

4.2.1 定义登录页面的视图函数:login/logout;
4.2.2 开发index.html,继承home.html并添加{% block content %} {% endblock %}区块;
4.2.3 home/home.html页面中{{ url_for('home.login') }} 和{{ url_for('home.logout') }}的使用;



4.2.4 会员注册页面的搭建过程;


4.2.5 会员中心页面搭建;

4-3 电影列表-搜索页面搭建
4.3.1 电影列表页面搭建;
4.3.2 首页index.html呈现;

4.3.3 电影搜索页面搭建;

4-4 电影详情页-404页面搭建
4.4.1 404页面处理;
4.4.2 404视图函数代码在app/__init__.py中编写;
app/__init__.py;
1#!/usr/bin/python3 2# -*- coding:utf-8 -*- 3# Project: MicroFilm 4# Software: PyCharm 5# Time : 2018-09-28 16:36 6# File : __init__.py.py 7# Author : 天晴天朗 8# Email : tqtl@tqtl.org 9 10from flask import Flask, render_template 11 12app = Flask(__name__) 13 14app.debug = True 15 16from app.home import home as home_blueprint 17from app.admin import admin as admin_blueprint 18 19app.register_blueprint(home_blueprint) 20app.register_blueprint(admin_blueprint, url_prefix="/admin") 21 22 23@app.errorhandler(404) 24def page_not_found(error): 25 return render_template("home/404.html"), 404


5-1 管理员登录-后台布局搭建
5.1.1 后台布局搭建;
5.1.2 管理员的登录和退出;
1#!/usr/bin/python3 2# -*- coding:utf-8 -*- 3# Project: MicroFilm 4# Software: PyCharm 5# Time : 2018-09-28 16:38 6# File : views.py 7# Author : 天晴天朗 8# Email : tqtl@tqtl.org 9 10from . import admin 11from flask import render_template, redirect, url_for 12 13 14@admin.route("/") 15def index(): 16 return "<h1 style='color:blue'>This is admin site!<h1>" 17 18 19@admin.route("/login/") 20def login(): 21 return render_template("admin/login.html") 22 23 24@admin.route("/logout/") 25def logout(): 26 return redirect(url_for("admin.login"))





5.1.3 后台布局搭建;

5.1.4 include引用报错处理;


5.1.5 修改密码;

5-2 修改密码-控制面板-标签管理页面搭建
5.2.1 修改密码;

5.2.2 控制面板;


5.2.3 调整页面,显示内存仪表盘;

5.2.4 标签管理页面搭建;


5-3 电影管理-上映预告管理页面搭建
5.3.1 编辑电影和电影列表;


5.3.2 编辑上映预告和上映电影列表;


5-4 会员-收藏-评论管理页面搭建
5.4.1 会员列表;


5.4.2 评论管理页面搭建;


5-5 收藏-日志-角色管理页面搭建
5.5.1 收藏管理列表搭建;


5.5.2 操作日志列表;




5.5.3 角色管理列表搭建;


5.5.4 添加权限和权限列表;


5-6 管理员页面搭建
5.6.1 管理员页面搭建;


6-1 管理员登录
6.1.1 调整项目代码结构;
6.1.2 flask-wtf第三方模块的安装;
6.1.3 编写LoginForm类以及报错处理;






6-2 标签管理
6.2.1 标签管理;

6-3 电影管理-添加电影
6.3.1 电影管理;

6-4 电影管理-列表、删除、编辑
6.4.1 电影列表;
6-5 预告管理
6-6 会员管理
6-7 评论-收藏管理
6-8 修改密码
6-9 日志管理
7-1 权限管理
7-2 角色管理
7-3 管理员管理
7-4 访问权限控制
8-1 会员注册
8-2 会员登录
8-3 修改会员资料
8-4 修改密码
8-5 会员登录日志
9-1 上映预告-标签筛选-电影分页
9-2 电影搜索-电影详情
10-1 电影评论-统计
10-2 收藏电影
10-3 电影弹幕-代码优化及Bug处理
11-1 CentOS安装LNMP
11.1.1 LNMP即——Linux + Nginx + MySQL+Python;
- 安装Python解释器的依赖包 yum install openssl-devel bzip2-devel expat-deval gdbm-devel realine-devel gcc gcc-c++
- 解压缩Python-3.6.1.tgz
- yum install mariadb;systemctl start mariadb.service;
- 修改mariadb的字符集为utf8,my.cnf文件;
- yum install nginx;# 推荐使用yum安装
- yum install gcc gcc-c++ opensll-devel pere-devel httpd-tools;
- useradd nginx
- ./configure --prefix==/usr/local/nginx --user==nginx --group=nginx --with http_ssl_module --with-http_mp4_module --with-http_flv_module make&make install
- ln -s /usr/local/nginx /usr/sbin/
- nginx
- netstat -lntup|grep nginx

11-2 部署电影网站-流媒体访问限制
11.2.1 部署微电影网站;
- pip3 install -i https://pypi.douban.com/simple --trusted-host pypi.douban.com -r requirements.txt;
- scp -r movie_project root@192.168.0.1:/root/# 程序包;
- 数据库中导入初始化数据;source /root/movie.sql;
- cp -a movie_project /usr/local/html/下;
- nohup python manage.py runserver -h 127.0.0.1 -p 5000,开启四个进程;




11.2.2 流媒体的访问限制;
- 限制单个IP能发起的连接数:limit_conn addr:1;
- 限制视频速率:limit_rate 1024K;
- 修改配置后,一定记得重启nginx,重启之前进行语法检查!!!nginx -t ; sytemctl reload nginx;
nginx.conf;
1worker_processes 4; 2events { 3 worker_connections 262140; 4} 5http { 6 include mime.types; 7 default_type application/octet-stream; 8 sendfile on; 9 keepalive_timeout 65; 10 limit_conn_zone $binary_remote_addr zone=addr:5m; 11 upstream movie { 12 server 127.0.0.1:5001; 13 server 127.0.0.1:5002; 14 server 127.0.0.1:5003; 15 server 127.0.0.1:5004; 16 } 17 server { 18 listen 80; 19 server_name localhost; 20 location / { 21 root html; 22 index index.html index.htm; 23 proxy_pass http://movie; 24 } 25 location ~ \.flv$ { 26 flv; 27 limit_conn addr 4; 28 limit_rate 1024k; 29 rewrite ^/static/uploads/(.+?).flv$ /movie_project/app/static/uploads/$1.flv permanent; 30 } 31 location ~ \.mp4$ { 32 mp4; 33 limit_conn addr 4; 34 limit_rate 1024k; 35 rewrite ^/static/uploads/(.+?).mp4$ /movie_project/app/static/uploads/$1.mp4 permanent; 36 } 37 error_page 500 502 503 504 /50x.html; 38 location = /50x.html { 39 root html; 40 } 41 } 42}




