【Flask微电影】16.电影预告管理:增删查改
2018-11-11 本文已影响4人
吾星喵
个人博客,欢迎查看:https://blog.starmeow.cn/
Github地址:https://github.com/xyliurui/FlaskMovie
预告管理
预告增加
创建预告添加表单
class PreviewForm(FlaskForm):
title = StringField(
label='预告标题',
validators=[
DataRequired('请输入预告标题!')
],
description='请输入预告标题!',
render_kw={
'class': "form-control"
}
)
logo = FileField(
label='预告封面',
validators=[
DataRequired('请上传预告封面!')
],
)
这儿添加和更新使用同一个模板文件,直接将preview_add.html修改为preview_edit.html
修改preview_add预告增加视图
from app.admin.forms import LoginFrom, TagForm, MovieForm, PreviewForm
from app.models import Admin, Tag, Movie, Preview
@admin.route("/preview/add/", methods=['GET', 'POST'])
@admin_login_require
def preview_add():
form = PreviewForm()
if form.validate_on_submit():
data = form.data
if Preview.query.filter_by(title=data['title']).count() == 1:
flash('预告标题已存在,请检查!', category='err')
return redirect(url_for('admin.preview_add'))
file_logo = secure_filename(form.logo.data.filename) # 获取上传文件名字
file_save_path = app.config['UP_DIR'] # 文件上传保存路径
if not os.path.exists(file_save_path):
os.makedirs(file_save_path) # 如果文件保存路径不存在,则创建一个多级目录
import stat
os.chmod(file_save_path, stat.S_IRWXU) # 授予可读写权限
logo = change_filename(file_logo) # 文件重命名
form.logo.data.save(file_save_path + logo) # 保存文件到磁盘中
preview = Preview(
title=data['title'],
logo=logo # 只在数据库中保存文件名
)
db.session.add(preview)
db.session.commit()
flash('添加预告成功', 'ok')
return redirect(url_for('admin.preview_add'))
return render_template('admin/preview_edit.html', form=form)
增加模板中的消息显示alert_info.html模块
在app/templates/admin/目录下创建alert_info.html模板文件
{% with msgs = get_flashed_messages(category_filter=['ok']) %}
{% if msgs %}
<div class="alert alert-success alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<h4><i class="icon fa fa-check"></i> 成功!</h4>
{% for msg in msgs %}
<p>{{ msg }}</p>
{% endfor %}
</div>
{% endif %}
{% endwith %}
{% with msgs = get_flashed_messages(category_filter=['err']) %}
{% if msgs %}
<div class="alert alert-danger alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<h4><i class="icon fa fa-ban"></i> 失败!</h4>
{% for msg in msgs %}
<p>{{ msg }}</p>
{% endfor %}
</div>
{% endif %}
{% endwith %}
之后再其他模板中就不用重复编写,直接包含这个模块即可,使用方式:{% include 'admin/alert_info.html' %}
修改preview_edit.html预告编辑模板
由于添加和更新使用相同的模板,所以需要对访问url进行判断
{% extends 'admin/base.html' %}
{% block content %}
<section class="content-header">
<h1>微电影管理系统</h1>
<ol class="breadcrumb">
<li><a href="#"><i class="fa fa-dashboard"></i> 预告管理</a></li>
<li class="active">
{% if request.path == url_for('admin.preview_add') %}
添加预告
{% else %}
修改预告
{% endif %}
</li>
</ol>
</section>
<section class="content" id="showcontent">
<div class="row">
<div class="col-md-12">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">
{% if request.path == url_for('admin.preview_add') %}
添加预告
{% else %}
修改预告
{% endif %}
</h3>
</div>
<form role="form" method="post" enctype="multipart/form-data">
<div class="box-body">
{% include 'admin/alert_info.html' %}
<div class="form-group">
<label for="input_title">{{ form.title.label }}</label>
{{ form.title }}
{% for err in form.title.errors %}
<div class="col-md-12" style="color: red">{{ err }}</div>
{% endfor %}
</div>
<div class="form-group">
<label for="input_logo">{{ form.logo.label }}</label>
{{ form.logo }}
{% for err in form.logo.errors %}
<div class="col-md-12" style="color: red">{{ err }}</div>
{% endfor %}
{% if request.path != url_for('admin.preview_add') %}
<img src="{{ url_for('static', filename="media/"+preview.logo) }}" data-src="holder.js/700x320" style="margin-top:5px;" class="img-responsive" alt="">
{% endif %}
</div>
</div>
{{ form.csrf_token }}
<div class="box-footer">
{{ form.submit }}
</div>
</form>
</div>
</div>
</div>
</section>
{% endblock %}
{% block js %}
<script>
// 激活菜单栏
$(document).ready(function () {
$("#g-4").addClass('active');
$("#g-4-1").addClass('active');
})
</script>
{% endblock %}
image.png
image.png
假如数据库已存在的,会提示错误
image.png预告列表
修改preview_list预告显示视图
@admin.route("/preview/list/<int:page>/")
@admin_login_require
def preview_list(page=None):
page_previews = Preview.query.paginate(page=page, per_page=10)
return render_template('admin/preview_list.html', page_previews=page_previews)
修改preview_list.html预告显示模板
<div class="box-body table-responsive no-padding">
<table class="table table-hover">
{% include 'admin/alert_info.html' %}
<tbody>
<tr>
<th>编号</th>
<th>预告标题</th>
<th>预告封面</th>
<th>添加时间</th>
<th>操作事项</th>
</tr>
{% for preview in page_previews.items %}
<tr>
<td>{{ preview.id }}</td>
<td>{{ preview.title }}</td>
<td>
<img src="{{ url_for('static', filename='media/'+preview.logo) }}" style="max-height: 50px" data-src="holder.js/140x64" class="img-responsive center-block"
alt="">
</td>
<td>{{ preview.add_time }}</td>
<td>
<a class="label label-success">编辑</a>
<a class="label label-danger">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="box-footer clearfix">
{% import 'admin/pagination.html' as pg %}
{{ pg.render_pagination(page_previews, 'admin.preview_list') }}
</div>
image.png
需要修改base.html预告列表链接,增加page参数
<a href="{{ url_for('admin.preview_list', page=1) }}">
<i class="fa fa-circle-o"></i> 预告列表
</a>
预告删除
增加preview_delete预告删除视图
删除预告会将旧的图片文件删除
@admin.route("/preview/delete/<int:delete_id>/", methods=['GET'])
@admin_login_require
def preview_delete(delete_id=None):
if delete_id:
preview = Preview.query.filter_by(id=delete_id).first_or_404()
# 删除同时要从磁盘中删除封面文件
file_save_path = app.config['UP_DIR'] # 文件上传保存路径
# 如果存在将进行删除,不判断,如果文件不存在删除会报错
if os.path.exists(os.path.join(file_save_path, preview.logo)):
os.remove(os.path.join(file_save_path, preview.logo))
# 删除数据库,提交修改,注意后面要把与电影有关的评论都要删除
db.session.delete(preview)
db.session.commit()
# 删除后闪现消息
flash('删除预告成功!', category='ok')
return redirect(url_for('admin.preview_list', page=1))
修改preview_list.html删除预告链接
<a class="label label-danger" href="{{ url_for('admin.preview_delete', delete_id=preview.id) }}">删除</a>
image.png
编辑预告
增加preview_update预告修改视图
同样使用preview_edit.html视图
@admin.route("/preview/update/<int:update_id>/", methods=['GET', 'POST'])
@admin_login_require
def preview_update(update_id=None):
preview = Preview.query.get_or_404(update_id)
form = PreviewForm(
title=preview.title,
)
# 不验证上传文件
form.logo.validators = []
form.logo.render_kw = {'required': False}
if form.validate_on_submit():
data = form.data
if Preview.query.filter_by(title=data['title']).count() == 1 and preview.title != data['title']:
flash('预告标题已存在,请重新输入', category='err')
return redirect(url_for('admin.preview_update', update_id=update_id))
preview.title = data['title']
print(data['logo'], type(data['logo']), form.logo.data, type(form.logo.data))
# <FileStorage: 'ssh.jpg' ('image/jpeg')> <class 'werkzeug.datastructures.FileStorage'>
# <FileStorage: 'ssh.jpg' ('image/jpeg')> <class 'werkzeug.datastructures.FileStorage'>
# 上面两种方式结果一样
# 文件保存路径操作
file_save_path = app.config['UP_DIR'] # 文件上传保存路径
if not os.path.exists(file_save_path):
os.makedirs(file_save_path) # 如果文件保存路径不存在,则创建一个多级目录
import stat
os.chmod(file_save_path, stat.S_IRWXU) # 授予可读写权限
if form.logo.data: # 当有上传新的图片
if os.path.exists(os.path.join(file_save_path, preview.logo)):
os.remove(os.path.join(file_save_path, preview.logo)) # 删除旧图片
file_logo_name = form.logo.data.filename
preview.logo = change_filename(file_logo_name) # 得到新的文件名,保存到输入局
form.logo.data.save(file_save_path + preview.logo)
db.session.commit()
flash('预告信息修改成功!', category='ok')
return redirect(url_for('admin.preview_update', update_id=update_id))
return render_template('admin/preview_edit.html', form=form, preview=preview)
修改预告直接使用preview_edit.html模板
image.png当文件名存在时,会提示已存在。
image.png