功能需求介绍
-
本次模块实现一个对前台首页数据的新增和编辑
-
数据有:标题、内容、英文内容、视频地址
-
实现单一页面既能编辑又能新增
创建首页数据模块蓝图
在 admin 文件夹中创建 index 文件夹(包),并在该文件夹中创建 views.py 文件。
在 __init__.py
中:
from flask import Blueprint
# 创建蓝图对象
index_blue = Blueprint('index_blue', __name__)
from . import views
在 views.py 中:
# 导入蓝图对象
from . import index_blue
@index_blue.route('/admin/home/1')
@login_required
def index():
return render_template('admin/home/index.html')
在 app/__init__.py
中注册蓝图
# 首页数据模块
from app.admin.index import index_blue
app.register_blueprint(index_blue)
在 _sidebar.html
中写上路由地址
<li>
<a href="/admin/home/1">
<span class="am-icon-home"></span> 首页数据
</a>
</li>
模板
在 templates/admin/home 创建 index.html,添加如下代码:
{% extends "admin/common/app.html" %}
{% block content %}
<div class="admin-content-body">
<div class="page-header">
<ol class="am-breadcrumb am-breadcrumb-slash">
<li><a href="/admin">首页</a></li>
<li>首页数据</li>
</ol>
</div>
<div class="page-body">
<form class="am-form am-form-horizontal" enctype="multipart/form-data" action="" method="post">
<div class="am-tabs am-margin" data-am-tabs>
<div class="am-form-group">
<label for="name" class="am-u-sm-12 am-u-md-3 am-form-label">标题</label>
<div class="am-u-sm-12 am-u-md-5 am-u-end">
<input type="text" name="title" placeholder="输入标题">
</div>
</div>
<div class="am-form-group">
<label for="description" class="am-u-sm-12 am-u-md-3 am-form-label">内容(中文)</label>
<div class="am-u-sm-12 am-u-md-5 am-u-end">
<textarea rows="8" placeholder="请输入中文内容" name="content"></textarea>
</div>
</div>
<div class="am-form-group">
<label for="description" class="am-u-sm-12 am-u-md-3 am-form-label">内容(英文)</label>
<div class="am-u-sm-12 am-u-md-5 am-u-end">
<textarea rows="8" placeholder="请输入英文内容" name="en_content"></textarea>
</div>
</div>
<div class="am-margin-top">
<div class="am-u-md-3 am-form-label">欢迎视频</div>
<div class="am-u-md-9">
<div class="am-form-group am-form-file">
<button type="button" class="am-btn am-btn-success am-btn-sm">
<i class="am-icon-cloud-upload" id="loading"></i> 上传视频
</button>
<input type="file" id="upload_video" name="video_url">
</div>
<hr data-am-widget="divider" style=""
class="am-divider am-divider-dashed am-no-layout">
<div>
<video src=""
controls="controls"
id="video_show"
style="width: 350px;height: 160px;">
</video>
<span id="file_name"></span>
</div>
</div>
</div>
</div>
<div class="am-form-group">
<div class="am-u-sm-12 am-u-md-9 am-u-md-offset-3">
<button type="submit" class="am-btn am-btn-primary am-btn-sm am-radius">保 存</button>
</div>
</div>
</form>
</div>
</div>
{% endblock %}
{% block js %}
<script>
$(function () {
$("#upload_video").on("change", function () {
//获取文件对象
let file = event.target.files[0];
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function (e) {
// console.log(e);return;
$("#video_show").attr("src", e.target.result);
};
$("#file_name").text(file.name);
});
})
</script>
{% endblock %}
在 admin/common 中新建 flash.html 文件,添加代码:
{% with messages = get_flashed_messages() %}
{% if messages %}
<div class="am-g">
<div class="am-u-md-12">
<div class="am-alert" data-am-alert>
<button type="button" class="am-close">×</button>
<ul>
{% for message in get_flashed_messages() %}
<li>{{ message }}</li>
{% endfor %}
</ul>
</div>
</div>
</div>
{% endif %}
{% endwith %}
访问浏览器,即可看到对应页面。
创建数据库表
在 app/models.py 中
class Home(BaseModel, db.Model):
"""首页数据"""
__tablename__ = "home"
id = db.Column(db.Integer, primary_key=True) # 编号
title = db.Column(db.String(255), unique=True, nullable=False) # 标题
content = db.Column(db.Text(), nullable=False) # 中文内容
en_content = db.Column(db.Text(), nullable=False) # 英文内容
video_url = db.Column(db.String(255), unique=True, nullable=False) # 视频地址
pycharm 虚拟终端执行迁移
python manage.py db migrate -m 'init_tables' # 生成迁移文件
python manage.py db upgrade # 运行迁移
此时查看数据库,home 表已创建。
文件上传
文件上传的基本步骤
一个带有 enctype=multipart/form-data 的 标记,标记中含有 一个
应用通过请求对象的 files 字典来访问文件。
使用文件的 save() 方法把文件永久地保存在本地系统中。
基础实例,可参考:https://clwy.cn/guide/documents/python-clwy/flask/uploadfile-pro
上传文件到本地
上面的上传表单我们已做好,可以直接测试通过js就可以上传文件,但是随着form表单的提交,后端逻辑还没写,接下来实现后端部分。
在 utils/common.py 中:
from datetime import datetime
# 读取允许上传文件的格式、类型
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1] in constants.ALLOWED_EXTENSIONS
# 读取上传后加密的文件名
def change_filename(filename):
dt = datetime.now()
time = dt.strftime('%Y%m%d%H%M%S')
filename = time + filename
return filename
在 app/constants.py 中,添加上传配置文件:
UPLOAD_FOLDER = os.getcwd() + '/app/static/uploads/' # 上传文件保存的本地路径
ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'mp4']) # 允许上传的文件类型或格式
在 admin/index/views.py 中:
import os
from app.utils.common import login_required
# 导入蓝图对象
from . import index_blue
from flask import render_template, request, flash, redirect
from werkzeug.utils import secure_filename
from werkzeug.datastructures import FileStorage
# 导入模型
from app.models import Home
from app import constants, db
from app.utils.common import allowed_file, change_filename
@index_blue.route('/admin/home/1')
@login_required
def index():
home = Home.query.filter_by(id=1).first()
return render_template('admin/home/index.html', home=home)
@index_blue.route('/admin/home/edit/1', methods=['POST'])
@login_required
def edit():
if request.method == 'POST':
video_url = ''
file = request.files['video_url']
if file and allowed_file(file.filename):
filename = secure_filename(change_filename(file.filename))
file.save(os.path.join(constants.UPLOAD_FOLDER, filename))
video_url = os.path.join('uploads', filename) # 获取本地文件路径
home = Home.query.filter_by(id=1).first()
if home:
home.video_url = video_url
home.title = request.form['title']
home.content = request.form['content']
home.en_content = request.form['en_content']
db.session.commit()
flash('编辑成功')
return redirect(request.referrer)
else:
h = Home()
h.title = request.form['title']
h.content = request.form['content']
h.en_content = request.form['en_content']
h.video_url = video_url
db.session.add(h)
db.session.commit()
flash('新增成功')
return redirect(request.referrer)
最后,手动在 app/static 下创建 uploads 文件夹,用于保存上传成功后的文件。当然你也可以在代码中加上自动创建上传文件夹。
上传文件到七牛云
这里以上传图片为例,直接开始。
-
在七牛云官网上注册账号,进行实名认证,获得密钥。在对象存储中创建存储空间,获得七牛分配的域名即可。
-
安装七牛包,参考文档: https://developer.qiniu.com/kodo/sdk/1242/python
$ pip install qiniu
- 在 app/constants.py 中配置七牛域名:
# 七牛空间配置
QINIU_DOMIN_PREFIX = "https://xxx.xxx.com/"
ACCESS_KET = '************************'
SECRET_KEY = '************************'
BUCKET_NAME = 'xxx'
在 utils/common.py 中,定义上传文件方法:
# 七牛上传方法
from qiniu import Auth, put_data
def qiniu_upload(file_path):
access_key = constants.ACCESS_KET
secret_key = constants.SECRET_KEY
# 构建鉴权对象
q = Auth(access_key, secret_key)
# 要上传的空间
bucket_name = constants.BUCKET_NAME
# 生成上传 Token,可以指定过期时间等
token = q.upload_token(bucket_name, None, 3600)
ret, info = put_data(token, None, file_path)
if info.status_code == 200:
# 表示上传成功, 返回文件名
# 我们上传成功之后, 需要在别的页面显示图像, 因此需要返回图像名
return ret.get("key")
else:
# 表示上传失败
raise Exception("上传失败")
调用七牛 SDK 执行上传
from app.utils.common import allowed_file, qiniu_upload
@index_blue.route('xxx', methods=['POST'])
@login_required
def edit():
if request.method == 'POST':
file = request.files['image_url']
if file and allowed_file(file.filename):
# 上传到本地
# filename = secure_filename(change_filename(file.filename))
# file.save(os.path.join(constants.UPLOAD_FOLDER, filename))
# image_url = os.path.join('uploads', filename)
# 上传到七牛
file_data = file.read()
filename = qiniu_upload(file_data)
image_url = constants.QINIU_DOMIN_PREFIX + filename
# print(image_url)
运行项目,终端看到图片地址输出即可
原文地址:https://blog.csdn.net/huangdj321/article/details/113803794
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。