测开之路一百三十七:实现图片上传和查询渲染功能

两种办法:

1.把接收的图片存到工程的某一文件夹下,数据库的img字段下存对应的路径,要用的时候根据路径去找图片

2.把接收的图片转成二进制存到img字段下,要用的时候再把二进制转回图片

这里采用第一种:

必须的元素

<form action="/post_feedback/" enctype="multipart/form-data" method="POST" class="form-horizontal">
<input type="file" id="image" name="image">

post.html

<!--继承base.html-->{% extends ‘base.html‘ %}

<!--引用base.html预留的正文部分-->{% block main_content %}    <div class="row">        <div class="panel panel-default">            <div class="panel-heading">                <h4>问题反馈</h4>            </div>            <div class="panel-body " >                <!--添加图片需要的属性:enctype="multipart/form-data"-->                <form action="/post_feedback/" enctype="multipart/form-data" method="POST" class="form-horizontal">                    <div class="form-group">                        <label for="subject" class="control-label col-md-2">主题</label>                        <div class="col-md-6">                            <input type="text" class="form-control" id="subject" name="subject">                        </div>                    </div>                    <div class="form-group">                        <label for="category" class="control-label col-md-2">问题分类</label>                        <div class="col-md-2">                            <select name="category" id="category" class="form-control">                                <option value="1">产品质量</option>                                <option value="2">客户服务</option>                                <option value="3">购买支付</option>                            </select>                        </div>                    </div>                    <div class="form-group">                        <label for="username" class="control-label col-md-2">姓名</label>                        <div class="col-md-2">                            <input type="text" class="form-control" id="username" name="username">                        </div>                    </div>                    <div class="form-group">                        <label for="email" class="control-label col-md-2">邮箱</label>                        <div class="col-md-6">                            <input type="text" class="form-control" id="email" name="email">                        </div>                    </div>                    <div class="form-group">                        <label for="file_s" class="control-label col-md-2">图片</label>                        <div class="col-md-6">                            <input type="file" id="file_s" name="file_s">                        </div>                    </div>

                    <div class="form-group">                        <label for="body" class="control-label col-md-2">内容</label>                        <div class="col-md-6">                            <textarea name="body" id="body" cols="30" rows="10" class="form-control"></textarea>                        </div>                    </div>                    <div class="col-md-offset-2">                        <input type="submit" class="btn btn-primary" value="提交">                        <input type="reset" class="btn btn-default" value="重置">

                    </div>                </form>            </div>            <div class="panel-footer">

            </div>        </div>    </div>

{% endblock %}

视图层,省略参数验证步骤

@app.route("/post_feedback/", methods=["POST"])def post_feedback():    """ 提交视图 """    if request.method == ‘POST‘:  # 如果是post请求就获取表单值        subject = request.form.get(‘subject‘, None)        categoryid = request.form.get(‘category‘, 1)        username = request.form.get(‘username‘)        email = request.form.get(‘email‘)        body = request.form.get(‘body‘)        release_time = str(datetime.now())        state = 0        img_path = None        # 提交的内容包含图片,就获取图片名字用于插入数据库,并保存图片        if request.files.get(‘file_s‘, None):            img = request.files[‘file_s‘]            if allowed_file(img.filename):                # 为防止文件名重复,重命名文件                img_path = datetime.now().strftime(‘%Y%m%d%H%M%f‘) + os.path.splitext(img.filename)[1]                img.save(os.path.join(UPLOAD_FOLDER, img_path))        print(subject, categoryid, username, email, body, state, release_time, img_path)        conn = sqlite3.connect(DATABASE)        c = conn.cursor()        # 防止sql注入,用?代替值        sql = "insert into feedback (Subjeck, CategoryID, UserName, Email, Body, State, ReleaseTime, Image) values (?,?,?,?,?,?,?,?)"        c.execute(sql, (subject, categoryid, username, email, body, state, release_time, img_path))        conn.commit()        conn.close()        # 为防止因卡顿引起重复提交,提交过后跳转到填写页面        return redirect(url_for(‘feedback‘))

前台操作:

日志和文件

数据库

渲染:需要用到flask的send_from_directory来指定文件路径

@app.route(‘/profile/<filename>‘)def render_file(filename):    """ 呈现特定目录下的资源,用于jinja2模板调用渲染服务器的图片"""    return send_from_directory(UPLOAD_FOLDER, filename)  # uploads + feilename

# 编辑功能@app.route("/edit/<id>/")def edit(id=None):    """ 根据前端传过来的id返回编辑的html """    # 获取绑定的下拉列表    sql = "select ROWID,CategoryName from category"    categories = query_sql(sql)    # 获取当前id的信息,并绑定至form表单,以备修改    sql = "select rowid,* from feedback where rowid = ?"    curren_feedback = query_sql(sql, (id,), True)    # return str(curren_feedback)  # 查看查出来的数据顺序,方便html渲染排序    return render_template(‘edit.html‘, categories=categories, item=curren_feedback)

edit.html

<!--继承base.html-->{% extends ‘base.html‘ %}

<!--引用base.html预留的正文部分-->{% block main_content %}    <div class="row">        <div class="panel panel-default">            <div class="panel-heading">                <h4>问题反馈信息编辑</h4>            </div>            <div class="panel-body">                <!--保存的url-->                <form action="{{ url_for(‘save_edit‘) }}" method="POST" class="form-horizontal">                    <div class="form-group">                        <label for="subject" class="control-label col-md-2">主题</label>                        <div class="col-md-6">                            <!--渲染主题-->                            <input type="text" value="{{ item[‘Subjeck‘] }}" class="form-control" id="subject" name="subject">                            <!--拿到id,不渲染,用于保存的时候做sql条件-->                            <input type="hidden" value="{{ item[‘rowid‘] }}" class="form-control" id="rowid" name="rowid">                        </div>                    </div>                    <div class="form-group">                        <label for="category" class="control-label col-md-2">问题分类</label>                        <div class="col-md-2">                            <select name="category" id="category" class="form-control">                                <!--显示当前问题的问题分类-->                                {% for category in categories %}                                    <option {{ ‘selected=selected‘ if item[‘CategoryID‘]==category[‘rowid‘] else ‘‘ }} value="{{ category[‘rowid‘] }}">{{ category[‘CategoryName‘] }}</option>                                {% endfor %}                            </select>                        </div>                    </div>                    <div class="form-group">                        <label for="username" class="control-label col-md-2">姓名</label>                        <div class="col-md-2">                            <!--渲染姓名-->                            <input type="text" class="form-control" value="{{ item[‘UserName‘] }}" id="username" name="username">                        </div>                    </div>                    <div class="form-group">                        <label for="email" class="control-label col-md-2">邮箱</label>                        <div class="col-md-6">                            <!--渲染邮箱-->                            <input type="text" class="form-control" value="{{ item[‘Email‘] }}" id="email" name="email">                        </div>                    </div>                    <div class="form-group">                        <label for="image" class="control-label col-md-2">图片</label>                        <div class="col-md-6">                            <img src="{{ url_for(‘render_file‘, filename=item.Image) }}" alt="{{ item.Subject }}">                            <input type="file" id="image" name="image">                        </div>                    </div>

                    <div class="form-group">                        <!--渲染内容-->                        <label for="body" class="control-label col-md-2">内容</label>                        <div class="col-md-6">                            <textarea name="body" id="body" cols="30" rows="10" class="form-control">{{ item[‘Body‘] }}</textarea>                        </div>                    </div>                    <!--增加回复内容、发布时间和处理状态-->                    <div class="form-group">                        <label for="reply" class="control-label col-md-2">回复</label>                        <div class="col-md-6">                            <!--渲染回复-->                            <textarea name="reply" id="reply" cols="30" rows="10" class="form-control">{{ item[‘Reply‘] if item[‘Reply‘] }}</textarea>                        </div>                    </div>                    <div class="form-group">                        <label for="releasetime" class="control-label col-md-2">发布时间</label>                        <div class="col-md-6">                            <input type="text" value="{{ item[‘ReleaseTime‘] }}"  name="releasetime" id="releasetime" class="form-control">                        </div>                    </div>                    <div class="form-group">                        <label for="state" class="control-label col-md-2">处理状态</label>                        <div class="col-md-6">                            <!--渲染处理状态-->                            <input type="checkbox" name="state" id="state" {{ ‘checked=checked‘ if item[‘State‘] == 1 else ‘‘}} >                        </div>                    </div>

                    <div class="col-md-offset-2">                        <input type="submit" class="btn btn-primary" value="提交">                        <input type="reset" class="btn btn-default" value="重置">                        <!--如果不想修改了,点击回到列表页-->                        <a href="{{ url_for(‘list‘) }} " class="btn btn-default">点击回到列表页</a>                    </div>                </form>            </div>            <div class="panel-footer">

            </div>        </div>    </div>

{% endblock %}

页面触发

完整的视图函数

# coding:utf-8import sqlite3from datetime import datetimefrom flask import Flask, request, render_template, redirect, url_for, g, send_from_directory

app = Flask(__name__)

DATABASE = r‘.\db\feedbach.db‘

‘=======================封装sql助手函数=============================‘

def make_dicts(cursor, row):    """ 将游标获取的Tuple根据数据库列表转换为dict """    return dict((cursor.description[idx][0], value) for idx, value in enumerate(row))

def get_db():    """ 获取(简历数据库链接)    g: flask内置的变量:g = LocalProxy(partial(_lookup_app_object, "g"))    """    db = getattr(g, ‘_database‘, None)    if not db:        db = g._database = sqlite3.connect(DATABASE)        db.row_factory = make_dicts    return db

def execute_sql(sql, params=()):    """ 执行sql语句不返回数据结果 insert、update、delete """    c = get_db().cursor()    c.execute(sql, params)    c.connection.commit()

def query_sql(sql, params=(), one=False):    """ 查询数据 one=False的时候返回多条"""    c = get_db().cursor()    result = c.execute(sql, params).fetchall()    c.close()    return (result[0] if result else None) if one else result

@app.teardown_appcontext  # 在当前app上下文销毁时执行def close_connection(exeption):    """ 关闭数据库 """    db = getattr(g, ‘_database‘, None)    if db is not None:        db.close()

‘========================================================================‘

@app.route("/")def index():    return render_template(‘base.html‘)

@app.route(‘/login/‘, methods=[‘GET‘, ‘POST‘])def login():    """ 登录 """    if request.method == ‘POST‘:        username = request.form.get(‘username‘)        password = request.form.get(‘password‘)        sql = ‘select count(*) as [Count] from UserInfo where username = ? and password = ?‘        result = query_sql(sql, (username, password), True)        if int(result.get(‘Count‘)) > 0:            return redirect(url_for(‘list‘))        return ‘用户名或密码错误‘    return render_template(‘login.html‘)

# 模板继承@app.route("/feedback/")def feedback():    return render_template(‘post.html‘)

UPLOAD_FOLDER = r‘.\uploads‘  # 声明存文件的目录ALLOWED_EXTENSIONS = [‘.jpg‘, ‘.png‘, ‘.gif‘]  # 允许上传的后缀,限制上传格式

import os

def allowed_file(filename):    """ 判断文件是否允许上传 """    # filename = ‘asdasdasd.jpg‘    _, ext = os.path.splitext(filename)    return ext.lower() in ALLOWED_EXTENSIONS  # 把后缀转为小写

@app.route("/post_feedback/", methods=["POST"])def post_feedback():    """ 提交视图 """    if request.method == ‘POST‘:  # 如果是post请求就获取表单值        subject = request.form.get(‘subject‘, None)        categoryid = request.form.get(‘category‘, 1)        username = request.form.get(‘username‘)        email = request.form.get(‘email‘)        body = request.form.get(‘body‘)        release_time = str(datetime.now())        state = 0        img_path = None        # 提交的内容包含图片,就获取图片名字用于插入数据库,并保存图片        if request.files.get(‘file_s‘, None):            img = request.files[‘file_s‘]            if allowed_file(img.filename):                # 为防止文件名重复,重命名文件                img_path = datetime.now().strftime(‘%Y%m%d%H%M%f‘) + os.path.splitext(img.filename)[1]                img.save(os.path.join(UPLOAD_FOLDER, img_path))        print(subject, categoryid, username, email, body, state, release_time, img_path)        conn = sqlite3.connect(DATABASE)        c = conn.cursor()        # 防止sql注入,用?代替值        sql = "insert into feedback (Subjeck, CategoryID, UserName, Email, Body, State, ReleaseTime, Image) values (?,?,?,?,?,?,?,?)"        c.execute(sql, (subject, categoryid, username, email, body, state, release_time, img_path))        conn.commit()        conn.close()        # 为防止因卡顿引起重复提交,提交过后跳转到填写页面        return redirect(url_for(‘feedback‘))

@app.route("/list/")def list():    """ 展示所有问题 """    sql = "select ROWID,* from feedback order by ROWID DESC"    # feedbacks = query_sql(sql)    # print(feedbacks)    key = request.args.get(‘key‘, ‘‘)    sql = ‘select f.ROWID,f.*,c.CategoryName from feedback f INNER JOIN category c on c.ROWID = f.CategoryID where f.Subjeck like ? order by f.ROWID‘    feedbacks = query_sql(sql, (f‘%{key}%‘,))    return render_template(‘feedback-list.html‘, items=feedbacks)

@app.route(‘/del/<id>/‘)def delete_feedback(id=0):    """ 删除问题 ,前端传id"""    conn = sqlite3.connect(DATABASE)    c = conn.cursor()    sql = "delete from feedback where ROWID = ?"    c.execute(sql, (id,))    conn.commit()    conn.close()    return redirect(url_for(‘list‘))

@app.route(‘/profile/<filename>‘)def render_file(filename):    """ 呈现特定目录下的资源,用于jinja2模板调用渲染服务器的图片"""    return send_from_directory(UPLOAD_FOLDER, filename)  # uploads + feilename

# 编辑功能@app.route("/edit/<id>/")def edit(id=None):    """ 根据前端传过来的id返回编辑的html """    # 获取绑定的下拉列表    sql = "select ROWID,CategoryName from category"    categories = query_sql(sql)    # 获取当前id的信息,并绑定至form表单,以备修改    sql = "select rowid,* from feedback where rowid = ?"    curren_feedback = query_sql(sql, (id,), True)    # return str(curren_feedback)  # 查看查出来的数据顺序,方便html渲染排序    return render_template(‘edit.html‘, categories=categories, item=curren_feedback)

@app.route("/save_edit/", methods=[‘POST‘])def save_edit():    """ 保存编辑 """    if request.method == ‘POST‘:        id = request.form.get(‘rowid‘, None)        reply = request.form.get(‘reply‘)        state = 1 if request.form.get(‘state‘, 0) == ‘on‘ else 0        sql = ‘update feedback set Reply=?, State=? where rowid=?‘        conn = sqlite3.connect(DATABASE)        c = conn.cursor()        c.execute(sql, (reply, state, id))        conn.commit()        conn.close()    return redirect(url_for(‘list‘))

if __name__ == ‘__main__‘:    app.run(        debug=True    )

原文地址:https://www.cnblogs.com/zhongyehai/p/11478790.html

时间: 2024-10-07 06:59:09

测开之路一百三十七:实现图片上传和查询渲染功能的相关文章

测开之路一百二十七:flask之构造response对象

可以使用flask.make_response构造自定义响应信息 构造一个响应信息为文本,状态码为404 响应 响应数据为json,状态码为200 返回html # coding:utf-8from flask import Flask, make_response, render_templateimport json app = Flask(__name__) @app.route("/rp/")def send_response(): """ 构造响

测开之路一百三十六:错误消息闪回提示

错误消息提示:flask.flash 视图 app.secret_key = 'qoihf2397r21380r2/./ad' # 加密的安全码,越复杂越好,flask后台自动进行加密 @app.route('/login/', methods=['GET', 'POST'])def login(): """ 登录 """ if request.method == 'POST': username = request.form.get('user

测开之路一百三十八:会话管理之session

session管理和使用,需要用到flask的session模块和设置安全码:app.secret_key 比如列表页和编辑功能只能给admin用 列表页 编辑页 添加session 登录成功时,把username添加到session里面 app.secret_key = 'qoihf2397r21380r2/./ad' # 加密的安全码,越复杂越好,flask后台自动进行加密 @app.route('/login/', methods=['GET', 'POST'])def login():

测开之路一百五十二:基于jquery的ajax实现(load、get、ajax)

ajax除了用原生的js实现之外,也可以使用jquery实现,而且用jquery更方便 看一个简单的示例,保留上一篇的content路由和html,实现上一篇一样的功能,点击获取内容,局部刷新 准备一个页面用于被调用 <h1>这是content.html的h1标签</h1><p style="background: red"> 这是content.html的p标签,红色 <a href="https://www.baidu.com/&

测开之路一百零三:jquery元素和标签的插入与删除

标签内插入 标签外插入 给标签加标签 !DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>元素和标签插入</title> <script src="https://cdn.bootcss.com/jquery/2.2.4/jquery.min.js"></script><

测开之路一百零二:jquery元素操作

jquery对元素操作,获取/替换文本(.text()).html(.html()).属性(.attr()).值(.val()) html代码 text() 根据标签获取文本值 同一个标签下筛选明细 最后一个元素 第一个元素 替换文本 html 获取html 替换html <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>

测开之路一百零五:bootstrap的两种引用方式

一:下载到本地引用: 3.3.7版本:https://getbootstrap.com/docs/3.3/getting-started/#download 下载后解压到本地项目中引用 第二种,cdn标签引用:https://www.bootcdn.cn/twitter-bootstrap/ 为了稳定,找3.3.7版本,min.css,复制标签:<link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap

测开之路一百零一:jquery文字特效、动画、方法链

文字特效 html内容 1.卷起/展开 2.隐藏/显示 3.淡入淡出 <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title> <!--<script src="../js/jquery-3.4.1.min.js"></script>--&g

测开之路一百:jquery引用、语法、事件

工作中一般会使用jquery代替js,jquery官网:https://jquery.com/ 引用jquery: 第一种方式:下载引用: jquery下载官网:https://jquery.com/download/ 下载压缩版本:右键-链接另存为,保存到项目的js下 引用 第二种方式:CDN引入:https://www.bootcdn.cn/jquery/ 为了稳定,使用2.2.4版本,直接复制标签到script标签下 jquery语法:$("选择器").事件(函数); 准备htm