Python-Flask实现电影系统管理后台
项目描述
该项目实现电影系统的后台接口,包括用户,电影,场次,订单,评论,优惠券,推荐,收藏等多个模块,同时提供一个管理后台进行操作和管理。使用Swagger使用接口的可视化,方便测试。
项目截图
项目结构
MovieAdmin
├── requirements.txt # 第三方库依赖文件
└── src
├── app
│ ├── admin # 管理后台文件
│ │ ├── admin.py
│ │ ├── __init__.py
│ │ └── views.py
│ ├── api # 接口文件
│ │ ├── comment.py
│ │ ├── coupon.py
│ │ ├── favorite.py
│ │ ├── __init__.py
│ │ ├── movie.py
│ │ ├── order.py
│ │ ├── password.py
│ │ ├── screen.py
│ │ ├── session.py
│ │ └── user.py
│ ├── __init__.py
│ ├── models.py # 数据库模型
│ ├── static # 静态文件,保存用户头像和电影海报等
│ │ ├── images
│ │ │ ├── poster
│ │ │ └── user
│ │ │ └── default.jpg
│ │ └── js
│ │ ├── jquery-3.2.1.min.js
│ │ └── md5.min.js
│ ├── templates
│ │ ├── admin
│ │ │ └── index.html
│ │ └── admin.html
│ └── utils.py
├── instance # 私密配置文件夹
│ ├── __init__.py
│ └── secure_conf.py
└── server.py # 主服务运行文件
项目运行
安装Python2.7环境
安装第三方依赖
pip install -r requirements.txt
运行
python server.py
运行后会在 src 目录下生成 data.sqlite
文件,存储数据库相关数据,访问 http://localhost:5000/admin/ 进入后台管理系统,管理系统账号密码保存在 src/instance/secure_conf.py
中,可自行更改。
项目实现
数据库建模
电影系统的主要功能是用户可以浏览电影信息并选择场次和座位进行下单购票,完成支付后会随机赠送优惠券,可在下次购票时使用。观看完电影之后可进行电影评论,用户也可以收藏电影,首页会定期推荐新上映的热门电影,因此该项目至少涉及以下几张数据表:用户表,电影表,场次表,订单表,评论表,优惠券表,推荐表,收藏表。
完整的数据库模型如下图:
以上数据库模型,以users为例,对应的sql语句如下:
-- ----------------------------
-- Table structure for users 用户表
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` varchar(11) NOT NULL COMMENT '用户id(手机号码)',
`password` varchar(32) NOT NULL COMMENT '登录密码',
`payPassword` varchar(32) NOT NULL COMMENT '支付密码',
`nickname` varchar(20) NOT NULL DEFAULT '' COMMENT '昵称',
`money` float NOT NULL COMMENT '余额',
`description` varchar(50) NOT NULL DEFAULT '' COMMENT '个性签名',
`avatar` varchar(32) NOT NULL DEFAULT '' COMMENT '头像路径',
`isAdmin` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
对象关系映射 ORM
对象关系映射(Object Relational Mapping,简称ORM),用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”。对象关系映射(Object-Relational Mapping)提供了概念性的、易于理解的模型化数据的方法。在大多数的 Web 应用中,都会将数据存储在关系型数据库中,使用 ORM 技术可以在代码通过操作对象实现数据库操作,无需自己写sql语句,如前面一大段建表的语句,ORM模型的简单性简化了数据库查询过程。使用ORM查询工具,用户可以访问期望数据,而不必理解数据库的底层结构。Flask 中可使用Flask-SQLAlchemy
来实现 ORM。
models.py
中定义了每张数据库表对应的对象,通过对这些对象的操作,可以直接实现对数据库的增删改查,无需编写sql语句。以订单表为例:
# -*- coding: utf-8 -*-
from datetime import datetime, date
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Order(db.Model):
"""订单"""
__tablename__ = 'orders'
__table_args__ = {'mysql_engine': 'InnoDB'} # 支持事务操作和外键
id = db.Column(db.String(32), primary_key=True)
screenId = db.Column(db.String(32), db.ForeignKey('screens.id'), nullable=False)
seat = db.Column(db.PickleType, doc='座位号(逗号分隔)', nullable=False)
username = db.Column(db.String(32), db.ForeignKey('users.id'), nullable=False)
createTime = db.Column(db.DateTime, doc='创建时间', nullable=False)
status = db.Column(db.Boolean, doc='订单状态(0:未支付,1:已支付)', default=0, nullable=False)
couponId = db.Column(db.String(32), db.ForeignKey('coupons.id'))
payPrice = db.Column(db.Float, doc='实际支付', nullable=False)
totalPrice = db.Column(db.Float, doc='原价', nullable=False)
管理系统
成功使用 ORM 建了项目所需的数据库表,现在我们要考虑一个问题,我们要怎么管理数据库中的数据呢,比如一个电影系统,肯定会有电影的信息和上映的场次信息,这个时候就需要一个后台管理系统,登录该系统后可以对数据库中的数据进行增删改查。使用Flask-Admin
可以很方便的构建一个后台管理系统
初始化
from flask import Flask
from flask_admin import Admin
app = Flask(__name__)
admin = Admin(app, name=u'电影管理系统') # 等价于下面两句
# admin = Admin(name=u'电影管理系统')
# admin.init_app(app)
app.run()
运行之后访问 http://localhost:5000/admin/ 就可以看到一个简单的管理界面。
增加视图
作为后台管理系统,当然需要添加登录界面,保证管理系统的安全性,用Flask-Login
做身份验证,Flask-WTF
防止跨站请求伪造攻击(CSRF)。
views.py
文件中,添加一个登录表单的类,其中的 User 类就是数据模型中的用户表,此时 User 类还需要继承 flask_login 中的UserMixin类。
from models import User
from flask_wtf import FlaskForm
from wtforms import fields, validators, ValidationError
class LoginForm(FlaskForm):
"""登录表单"""
username = fields.StringField(validators=[validators.data_required()])
password = fields.PasswordField(validators=[validators.data_required()])
def validate_username(self, field):
"""登录校验"""
user = self.get_user()
if user is None:
raise ValidationError('Invalid user')
if self.password.data != user.password:
raise ValidationError('Invalid password')
def get_user(self):
return User.query.filter_by(id=self.username.data, isAdmin=1).first()
有了登录表单之后,增加一个视图,如果未登录就重定向到登录界面,已登录就显示管理系统首页,这里需要在templates文件夹中添加模板文件。
import flask_login as login
from flask_login import login_required
from flask_admin import expose, AdminIndexView, helpers
class MyAdminIndexView(AdminIndexView):
@expose('/')
def index(self):
if not isAdmin():
return redirect(url_for('.login_view'))
return super(MyAdminIndexView, self).index()
@expose('/login/', methods=('GET', 'POST'))
def login_view(self):
form = LoginForm(request.form)
if helpers.validate_form_on_submit(form):
user = form.get_user()
login.login_user(user)
if isAdmin():
return redirect(url_for('.index'))
self._template_args['form'] = form
return super(MyAdminIndexView, self).index()
@expose('/logout/')
@login_required
def logout_view(self):
login.logout_user()
return redirect(url_for('.login_view'))
数据库模型视图
为数据库中的每个张表增加专用的管理页面。比如现在要为电影单独添加一个管理页面,只需新建一个继承ModelView的类
from wtforms import fields
from flask_admin.contrib.sqla import ModelView
class MovieModelView(ModelView):
column_exclude_list = ('description',) # 不显示的字段
# 表单字段
form_columns = ('expired', 'name', 'poster', 'description',
'playingTime', 'duration', 'movieType', 'playingType')
form_create_rules = form_columns[1:] # 新建时显示的字段
form_overrides = {'poster': fields.FileField} # 重写表单类型
# 自定义字段显示
form_args = {
'movieType': {
'render_kw': {
'placeholder': '电影类型, 中文逗号分隔'
}
}
}
# 当模型的数据改变时触发(新建或修改)
def on_model_change(self, form, movie, is_created):
# do something
pass
然后初始化登录,添加模型视图即可
# -*- coding: utf-8 -*-
from views import *
import flask_login as login
from flask_admin import Admin
from models import db, Movie, User
def init_login(app):
"""初始化登录"""
login_manager = login.LoginManager()
login_manager.init_app(app)
# Create user loader function
@login_manager.user_loader
def load_user(id):
return User.query.get(id)
admin = Admin(name='管理系统', template_mode='bootstrap3',
index_view=MyAdminIndexView(), base_template='admin.html')
movieModelView = MovieModelView(Movie, db.session, name='电影管理')
admin.add_view(movieModelView)
效果如下:
SwaggerUI
有了管理后台,就可以开始编写后台接口了,Flask-RESTPlus
增加了对快速构建 REST API的支持。它配置非常简单,很容易上手,而且它提供了装饰器和工具集合来描述API 并且集成了 Swagger UI 界面。
在 REST 中,一个 URI 标识一个资源,Flask-RESTPlus 中有一个Resource类,继承这个类并实现get,post,delete,patch等函数即可处理对应的 HTTP 请求。下面以收藏模块为例:
# *-* coding: utf-8 *-*
from flask import request
from app.utils import UUID
from app.models import Favorite, Movie, db
from flask_restplus import Namespace, Resource
from flask_login import current_user, login_required
api = Namespace('favorite', description='收藏模块')
@api.route('/')
class FavoritesResource(Resource):
@login_required
def get(self):
"""获取收藏列表(需登录)"""
return [f.__json__() for f in current_user.favorites], 200
@api.doc(parser=api.parser().add_argument(
'movieId', type=str, required=True, help='电影id', location='form')
)
@login_required
def post(self):
"""收藏电影(需登录)"""
mid = request.form.get('movieId', '')
movie = Movie.query.get(mid)
if movie is None:
return {'message': '电影不存在'}, 233
movie = current_user.favorites.filter_by(movieId=mid).first()
if movie is not None:
return {'message': '不能重复收藏同部电影'}, 233
favorite = Favorite()
favorite.id = UUID()
favorite.username = current_user.id
favorite.movieId = mid
db.session.add(favorite)
db.session.commit()
return {'message': '收藏成功', 'id': favorite.id}, 200
@api.route('/<id>')
@api.doc(params={'id': '收藏id'})
class FavoriteResource(Resource):
@login_required
def delete(self, id):
"""取消收藏(需登录)"""
favorite = current_user.favorites.filter_by(id=id).first()
if favorite is None:
return {'message': '您没有这个收藏'}, 233
db.session.delete(favorite)
db.session.commit()
return {'message': '取消收藏成功'}, 200
@api.route
装饰器是路由监听,@login_required
装饰器来自于 Flask-Login ,被装饰的函数需要用户登录,@api.doc
是文档说明,在后面的 Swagger UI 部分就能看到它的作用了。
创建了资源之后,只需要进行初始化即可实现 RESTful 服务。
# *-* coding: utf-8 *-*
from flask import Flask
from flask_restplus import Api
from favorite import api as ns1
api = Api(
title='MonkeyEye',
version='1.0',
description='电影系统API',
doc='/swagger/', # Swagger UI: http://localhost:5000/swagger/
catch_all_404s=True,
serve_challenge_on_401=True
)
api.add_namespace(ns1, path='/api/favorites')
app = Flask(__name__)
api.init_app(app)
if __name__ == '__main__':
app.run()
实现了 REST API 之后,我们要怎么测试这些接口呢,有没有一种操作简便的方法呢? Flask-RESTPlus 中就自带了 Swagger UI 界面,可以直接访问该界面查看 API 并进行测试,前面我们用@api.doc
修饰的资源和方法都会在 Swagger UI 界面呈现出来,Api(doc=/swagger/) 指定了 Swagger UI 的路径,效果如下图:
改进优化
为了例子能够简单快速运行,减少环境依赖,删除了原项目很多的功能点:
- MySQL数据库,例子中改用sqlite,可自行安装其他数据库,修改配置文件中的数据库URL即可。
- 手机号注册,短信验证码功能
- 使用QQ邮箱发送重置密码右键功能
- gunicorn + Nginx 部署,提高程序性能
参考链接:
- Flask 文档:https://dormousehole.readthedocs.io/en/latest/
- Flask-Admin 教程:http://flask123.sinaapp.com/article/57/
- Flask-RESTplus 教程:https://www.cnblogs.com/leejack/p/9162367.htmlPython-Flask实现电影系统管理后台
Python-Flask实现电影系统管理后台的更多相关文章
- Python Flask搭建一个视频网站实战视频教程
点击了解更多Python课程>>> Python Flask搭建一个视频网站实战视频教程 第1章 课程介绍 第2章 预备开发环境 第3章 项目分析.建立目录及模型规划 第4章 建立前 ...
- Taffy Web开发,Python Flask实践详解
1. 前言 最近为Taffy自动化测试框架写了个页面,主要实现了用例管理.执行,测试报告查看管理.发送邮件及配置等功能. 2. 实现细节 页面使用Python Flask +Bootstrap开发,还 ...
- 使用Nginx+Uwsgi部署Python Flask项目
第一次用Flask做Web(也是第一次用Python做Web),在部署的时候遇到了不少问题,现在将过程就下来,供在这方面也有疑惑的人参考.(PS:使用Apache+mod_wsgi部署模式的可以参考另 ...
- python操作三大主流数据库(6)python操作mysql⑥新闻管理后台功能的完善(增、ajax异步删除新闻、改、查)
python操作mysql⑥新闻管理后台功能的完善(增.删.改.查)安装表单验证D:\python\python_mysql_redis_mongodb\version02>pip instal ...
- 前端和后端的数据交互(jquery ajax+python flask+mysql)
上web课的时候老师布置的一个实验,要求省市连动,基本要求如下: 1.用select选中一个省份. 2.省份数据传送到服务器,服务器从数据库中搜索对应城市信息. 3.将城市信息返回客户,客户用sele ...
- python flask实现小项目方法
本文目的是为了完成一个项目用到的flask基本知识,例子会逐渐加深.最好对着源码,一步一步走. 下载源码,运行 pip install -r requirements.txt 建立环境 python ...
- Python: Flask框架简单介绍
接触Python之后我第一次听说Flask,我就根据自己搜罗的知识尽可能简洁的说出来.如果不准确的地方还请指正,谢谢. Flask是什么? Flask是基于Python编写的微 ...
- Taffy自动化测试框架Web开发,Python Flask实践详解
1. 前言 最近为Taffy自动化测试框架写了个页面,主要实现了用例管理.执行,测试报告查看管理.发送邮件及配置等功能. 本页面适用所有基于taffy/nose框架编写的自动化测试脚本,或基于un ...
- 知了课堂 Python Flask零基础 笔记整理
目录 起步 安装Python2.7: Python虚拟环境介绍与安装: pip安装flask: 认识url: URL详解 web服务器和应用服务器以及web应用框架: Flask 第一个flask程序 ...
随机推荐
- 一致性哈希算法(consistent hashing)(转)
原文链接:每天进步一点点——五分钟理解一致性哈希算法(consistent hashing) 一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网 ...
- .NET开发过程中的全文索引使用技巧之Solr(转)
前言:相信许多人都听说过.net开发过程中基于Lucene.net实现的全文索引,而Solr是一个高性能,基于Lucene的全文搜索服务器.同时对其进行了扩展,提供了比Lucene更为丰富的查询 ...
- iOS开发-CocoaPods实战
CocoaPods 是开发 OS X 和 iOS 应用程序的第三方库的依赖管理工具,如果是正常的开发不需要使用的第三方的代码,CocoaPods是不需要的,但是从实际情况上,为了提高开发效率,Coco ...
- js 处理URL实用技巧
escape().encodeURI().encodeURIComponent()三种方法都能对一些影响URL完整性的特殊字符进行过滤. 但后两者是将字符串转换为UTF-8的方式来传输,解决了 ...
- Word Embedding与Word2Vec
http://blog.csdn.net/baimafujinji/article/details/77836142 一.数学上的“嵌入”(Embedding) Embed这个词,英文的释义为, fi ...
- Tensorflow进行POS词性标注NER实体识别 - 构建LSTM网络进行序列化标注
http://blog.csdn.net/rockingdingo/article/details/55653279 Github下载完整代码 https://github.com/rockingd ...
- linux运维需要掌握的基础知识
踏入linux运维工程师这一职业,其实有很多工具技能需要掌握,下面我来给大家一一介绍. 1.shell脚本和另一个脚本语言,shell是运维人员必须具备的,不懂这个连入职都不行,至少也要写出一些系统管 ...
- sublime同步文件与siderbar
有时候,打开了sider bar,想和Eclipse.idea一样,每打开一个tab,就可以在左侧的sider bar 目录上面看到我当前的位置,于是找到了一个插件. SyncedSideBar 安装 ...
- [Canvas]碰撞球 增加小球间碰撞检测
请点此下载代码并用Chrome或是Firefox打开index.html 图例: 代码: <!DOCTYPE html> <html lang="utf-8"&g ...
- Google Java Style 中文版
Google Java Style 中文版 基于官方文档2013.12.19最后一次改动. 翻译人:Weir Zhang (zh.weir) 旁白:水平有限,很多地方只是意译.不准确的地方 ...