Django 集成 Editor 编辑器
Django 集成 Editor.md 编辑器
0.前提条件
为了更好的实现 Markdown 编辑器,这里使用了开源的 editor.md 用作页面上的 Markdown 编辑器,需要预先下载 Editor.md 的安装包到 Django 项目的静态文件目录下,如下所示
Django项目/
├── ../
├── static/
│ └── editor.md/
├── ../放置完成后,可以访问 editor.md 下的 examples/simple.html ,如果能够出现 editor.md 的编辑器效果,说明 editor.md 位置放置正确,如下图所示。

1.依赖配置安装
使用 pip 安装 markdown 扩展依赖。
pip install markdown确认 Django 项目的 settings.py 是否有以下配置,如果缺少则进行补充。
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
STATIC_URL = '/static/2.应用集成editor.md
修改要使用 markdown 编辑器的模型字段。
class ArticlePost(models.Model):
...
body = models.TextField() # 保存 Markdown 文本修改要使用 markdown 编辑器的表单字段。
# 写文章的表单类
class ArticlePostForm(forms.ModelForm):
class Meta:
widgets = {
'body': forms.Textarea(attrs={'id': 'id_content'}),
}配置 markdown 编辑器中上传图片的视图函数。
# 这一步存在问题,暂时不做实现
from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse
@csrf_exempt
def upload_image(request):
if request.method == 'POST' and request.FILES.get("editormd-image-file"):
f = request.FILES["editormd-image-file"]
today = datetime.now().strftime('%Y%m%d')
path = os.path.join("uploads", "article", today, f.name)
full_path = os.path.join(settings.MEDIA_ROOT, path)
os.makedirs(os.path.dirname(full_path), exist_ok=True)
with open(full_path, 'wb+') as destination:
for chunk in f.chunks():
destination.write(chunk)
return JsonResponse({
"success": 1,
"message": "上传成功",
"url": settings.MEDIA_URL + path
})
return JsonResponse({"success": 0, "message": "上传失败"})配置 markdown 编辑器中上传图片的路由函数。
urlpatterns = [
# markdown上传图片
path('upload_image/', views.upload_image, name='upload_image'),
path('success/', lambda r: HttpResponse("发布成功")),
]模版中嵌入 Editor.md。
<!-- 编辑器样式文件 -->
<head>
<link rel="stylesheet" href="{% static 'editor.md/css/editormd.min.css' %}" />
</head>
<!-- 表单内容 -->
<form method="post" action="." class="my-4">
{% csrf_token %}
<!-- {{ article_post_form.media }}
{{ article_post_form.as_p }}
<button type="submit" class="btn btn-primary">文章发表</button> -->
<div class="mb-3">
<label for="title" class="form-label">文章标题</label>
<input type="text" class="form-control" id="title" name="title" placeholder="请输入标题">
</div>
<div class="mb-3">
<label for="category" class="form-label">文章分类</label>
<select class="form-select" id="category" name="category">
{% for category in categories %}
<option value="{{ category.id }}">{{ category.name }}</option>
{% endfor %}
</select>
</div>
<div class="mb-3">
<label for="tag" class="form-label">文章标签</label>
<select multiple class="form-select" id="tag" name="tag">
{% for tag in tags %}
<option value="{{ tag.id }}">{{ tag.name }}</option>
{% endfor %}
</select>
<small class="form-text text-muted">按住 Ctrl (Windows) 或 ⌘ (Mac) 选择多个标签</small>
</div>
<div id="editor">
<textarea name="body" id="id_content" style="display:none;">{{ form.content.value }}</textarea>
</div>
<button type="submit" class="btn btn-primary">提交</button>
</form>
<!-- 这里一定要引用jquery,否则可能会导致无法加载编辑器 -->
<script src="{% static 'js/jquery-3.7.1.min.js' %}"></script>
<script src="{% static 'editor.md/editormd.min.js' %}"></script>
<script>
var editor = editormd("editor", {
width: "100%",
height: 500,
path: "{% static 'editor.md/lib/' %}",
imageUpload: true,
imageFormats: ["jpg", "jpeg", "png", "gif", "bmp", "webp"],
imageUploadURL: "{% url 'article:upload_image' %}",
});
</script>访问 markdown 编辑器的页面,如下图所示,说明 markdown 编辑器前端集成成功。

点击提交,正常不报错,后端集成成功,点击新增加的文章,能够查看识别到的markdown文章目录信息,应用集成editor.md 正常无报错。

3.markdown 上传图片
使用 editor.md 调用上传图片的接口会存在跨域和iframe问题,这里需要额外做一些设置。
在
settings.py中添加X-Frame-Options配置:# 允许同源iframe加载 X_FRAME_OPTIONS = 'SAMEORIGIN'修改
upload_image视图函数,添加跨域的响应头:@csrf_exempt def upload_image(request): if request.method == 'POST' and request.FILES.get("editormd-image-file"): f = request.FILES["editormd-image-file"] today = datetime.now().strftime('%Y%m%d') path = os.path.join("uploads", "article", today, f.name) full_path = os.path.join(settings.MEDIA_ROOT, path) os.makedirs(os.path.dirname(full_path), exist_ok=True) with open(full_path, 'wb+') as destination: for chunk in f.chunks(): destination.write(chunk) response = JsonResponse({ "success": 1, "message": "上传成功", "url": settings.MEDIA_URL + path }) # 添加跨域响应头 response["Access-Control-Allow-Origin"] = "*" response["Access-Control-Allow-Headers"] = "*" return response return JsonResponse({"success": 0, "message": "上传失败"})修改前端模版集成编辑器的配置代码,重点是添加最后两行的代码,如下所示:
var editor = editormd("editor", { width: "100%", height: 500, path: "{% static 'editor.md/lib/' %}", imageUpload: true, imageFormats: ["jpg", "jpeg", "png", "gif", "bmp", "webp"], imageUploadURL: "{% url 'article:upload_image' %}", crossDomainUpload: false, // 设置为false,因为我们在同一域名下 uploadCallbackURL: "", // 不需要回调URL });由于修改了
Django项目的配置文件,这里需要重启Django项目,重启后访问页面,能够正常上传图片。
点击确定后,
markdown编辑器界面能够正常展示上传的图片,如下所示: