Flask使用flask_sqlalchemy处理用户上传图片存入Product模型报错求助
Flask 商品图片上传功能完整实现方案
1. 模型字段定义
我们不会将图片二进制内容直接存入数据库,而是把图片的存储路径/文件名存入数据库,picture字段使用字符串类型即可:
class Product(db.Model): id = db.Column(db.Integer, primary_key=True) # auto +1 title = db.Column(db.String(20), nullable=False) price = db.Column(db.Integer, nullable=False) description = db.Column(db.Text) status = db.Column(db.Boolean, default=True) # 存储上传后的图片文件名,长度可根据需求调整 picture = db.Column(db.String(100))
2. 添加上传基础配置
在Flask应用初始化后添加以下配置,注意需要提前手动创建static/uploads目录用于存放上传的图片:
import os from uuid import uuid4 # 配置图片存储目录 app.config['UPLOAD_FOLDER'] = os.path.join(app.root_path, 'static', 'uploads') # 允许的图片后缀 ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'} # 限制单张图片最大为2MB app.config['MAX_CONTENT_LENGTH'] = 2 * 1024 * 1024 # 工具函数:校验文件后缀是否合法 def allowed_file(filename): return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
3. 路由逻辑修改
注意:前端提交商品信息的form表单必须添加enctype="multipart/form-data"属性,否则无法正常获取上传的图片文件
@app.route('/add_product', methods=['POST', 'GET']) def create(): if request.method == 'POST': title = request.form['title'] price = request.form['price'] description = request.form['description'] # 获取上传的图片文件对象 image_file = request.files.get('picture') pic_name = None # 校验文件是否合法 if image_file and allowed_file(image_file.filename): # 生成唯一文件名避免重名覆盖 ext = image_file.filename.rsplit('.', 1)[1].lower() pic_name = f"{uuid4().hex}.{ext}" # 保存图片到指定目录 image_file.save(os.path.join(app.config['UPLOAD_FOLDER'], pic_name)) # 将图片名传入商品实例 product = Product( title=title, price=price, description=description, picture=pic_name ) try: db.session.add(product) db.session.commit() return redirect('/') except: # 保存失败时删除已上传的图片 if pic_name: os.remove(os.path.join(app.config['UPLOAD_FOLDER'], pic_name)) return 'Error'
如果要求图片为必填项,可在上述文件校验的else分支返回错误提示,阻止商品创建。
4. 首页展示逻辑
在首页模板中遍历商品数据,用以下方式渲染图片即可:
{% for product in products %} <div class="product-item"> <h3>{{ product.title }}</h3> {% if product.picture %} <img src="{{ url_for('static', filename='uploads/' + product.picture) }}" alt="{{ product.title }}"> {% endif %} <p>价格:¥{{ product.price }}</p> <p>{{ product.description }}</p> </div> {% endfor %}
内容的提问来源于stack exchange,提问作者Jack Grealish
相关产品推荐
相关产品推荐

