两种办法:
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