You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flask Admin的编辑器文本区域上传图片?寻求更简易方案

如何在Flask Admin的富文本编辑器中实现简易图片上传

嘿,我来给你一个比flask-ckeditor更轻量的方案——完全不需要额外安装Python扩展,只用Flask原生功能+一个轻量的富文本编辑器(比如Summernote,直接用CDN引入就行)就能搞定。

第一步:先搞定Flask的文件上传基础配置

首先在你的Flask app里加上上传相关的配置和一个简单的上传接口:

from flask import Flask, request, jsonify, url_for
from flask_admin import Admin
from flask_admin.contrib.sqla import ModelView
import os
from werkzeug.utils import secure_filename
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SECRET_KEY'] = '换成你的密钥'
# 配置图片上传的文件夹,会自动创建这个目录
app.config['UPLOAD_FOLDER'] = os.path.join(app.root_path, 'static/uploads')
# 允许上传的图片格式
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
# 可选:设置最大上传文件大小,比如16MB
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024

# 自动创建上传目录
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)

db = SQLAlchemy(app)

# 检查文件格式是否合法的小工具函数
def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

# 处理图片上传的接口
@app.route('/upload-image', methods=['POST'])
def upload_image():
    if 'file' not in request.files:
        return jsonify({'error': '没找到上传的文件'}), 400
    file = request.files['file']
    if file.filename == '':
        return jsonify({'error': '请选择要上传的图片'}), 400
    if file and allowed_file(file.filename):
        # 用secure_filename处理文件名避免安全问题,可加UUID防止重名
        filename = secure_filename(file.filename)
        # 怕重名就加个UUID:
        # import uuid
        # filename = f"{uuid.uuid4().hex}_{filename}"
        file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
        file.save(file_path)
        # 返回图片的可访问URL,供编辑器插入
        img_url = url_for('static', filename=f'uploads/{filename}', _external=True)
        return jsonify({'url': img_url})
    return jsonify({'error': '不支持的图片格式'}), 400

第二步:给Flask Admin自定义富文本编辑器字段

假设你有一个需要富文本内容的模型,比如Post:

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(200), nullable=False)
    content = db.Column(db.Text)  # 这个字段要改成富文本编辑器

接下来我们要自定义一个富文本字段,把Summernote编辑器集成进去,替换掉默认的文本框:

from flask_admin.form import TextAreaField
from wtforms.widgets import HTMLString, TextArea

# 自定义编辑器的渲染组件
class RichTextWidget(TextArea):
    def __call__(self, field, **kwargs):
        # 先渲染默认的文本框,再加上Summernote的初始化代码
        base_html = super().__call__(field, **kwargs)
        return HTMLString(f"""
        {base_html}
        <!-- 引入Summernote的CDN资源,不用下载到本地 -->
        <link href="https://cdn.jsdelivr.net/npm/summernote@0.8.20/dist/summernote-bs4.min.css" rel="stylesheet">
        <script src="https://cdn.jsdelivr.net/npm/summernote@0.8.20/dist/summernote-bs4.min.js"></script>
        <script>
            $(document).ready(function() {{
                // 初始化Summernote编辑器
                $('#{field.id}').summernote({{
                    height: 350,  // 设置编辑器高度
                    callbacks: {{
                        // 监听图片上传事件
                        onImageUpload: function(files) {{
                            var formData = new FormData();
                            formData.append('file', files[0]);
                            // 调用我们刚才写的上传接口
                            $.ajax({{
                                url: '/upload-image',
                                method: 'POST',
                                data: formData,
                                contentType: false,
                                processData: false,
                                success: function(res) {{
                                    // 上传成功后把图片插入到编辑器里
                                    $('#{field.id}').summernote('insertImage', res.url);
                                }},
                                error: function(xhr) {{
                                    alert('图片上传失败:' + xhr.responseJSON.error);
                                }}
                            }});
                        }}
                    }}
                }});
            }});
        </script>
        """)

# 自定义富文本字段
class RichTextAreaField(TextAreaField):
    widget = RichTextWidget()

# 自定义ModelView,把content字段换成我们的富文本字段
class PostAdminView(ModelView):
    form_overrides = {
        'content': RichTextAreaField
    }

# 注册Admin和视图
admin = Admin(app, name='后台管理', template_mode='bootstrap4')
admin.add_view(PostAdminView(Post, db.session))

if __name__ == '__main__':
    with app.app_context():
        db.create_all()  # 创建数据库表
    app.run(debug=True)

第三步:测试功能

启动你的Flask应用,访问Admin页面(默认是/admin),创建或编辑Post的时候,就能看到带图片上传按钮的富文本编辑器了。点击图片按钮选择本地图片,上传成功后会自动插入到编辑器里,完美!

为啥这个方案更简易?

  • 不用安装额外的Python包,减少项目依赖。
  • 编辑器用CDN引入,不用折腾本地静态文件配置。
  • 上传逻辑是Flask原生实现的,代码简单,你想改啥都很方便(比如加图片压缩、改存储路径)。

一些生产环境的小提醒

  • 别用本地存储!生产环境建议把图片传到云存储(比如阿里云OSS、AWS S3),避免服务器存储满了。
  • 可以给上传接口加个权限验证,比如只有Admin用户能访问,防止恶意上传。
  • 要是不喜欢Summernote,换成TinyMCE或者其他轻量编辑器也可以,只要改一下初始化的JS代码就行。

内容的提问来源于stack exchange,提问作者Sadme Rame

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:14:56