Django使用edtor.md添加图片的支持
测试竟然只能在谷歌浏览器起作用。
模型
# 图片存储
class WiKiContentImage(models.Model):
wiki = models.ForeignKey(TitleTree, on_delete=models.CASCADE, null=True, blank=True, related_name='wiki_images', verbose_name='所属文章')
title = models.CharField(max_length=50, null=True, blank=True, verbose_name='标题')
image = models.ImageField(upload_to='images/wiki/%Y/%m', blank=True, null=True, verbose_name='图片')
created_user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True, related_name='wiki_images', verbose_name='上传人员')
created_time = models.DateTimeField(auto_now_add=True, null=True, blank=True, verbose_name='创建时间')
class Meta:
verbose_name = 'WiKi图集'
verbose_name_plural = verbose_name
def __str__(self):
return self.title
视图
编辑文章视图
# WiKi更新及创建视图
class WiKiContentEdit(View):
@method_decorator(login_required(login_url='/account/login/?next=/wiki/wiki_backend/'))
def get(self, request, title_id):
current_url = reverse('wiki:wiki_edit', kwargs={'title_id': title_id})
wiki_backend_url_list = get_group_url_list(current_url)
wiki_content = ''
wiki_title = get_object_or_404(TitleTree, id=title_id)
if WiKiContent.objects.filter(title__id=title_id):
show_content = True
wiki_content = WiKiContent.objects.get(title__id=title_id)
else:
show_content = False
titles = TitleTree.objects.all()
tags = Tag.objects.all()
# 推荐星级转换为列表
star_list = list(map(lambda x: {'num': x[0], 'mean': x[1]}, WiKiContent.STAR))
return render(request, 'backend/wiki_edit.html',
{
'titles': titles,
'tags': tags,
'wiki_content': wiki_content,
'show_content': show_content,
'title_id': title_id,
'wiki_title': wiki_title,
'WIKI_MENU_GROUP': wiki_backend_url_list,
'star_list': star_list,
})
@method_decorator(login_required(login_url='/account/login/?next=/wiki/wiki_backend/'))
def post(self, request, title_id):
title_new = request.POST.get('title_new')
content = request.POST.get('content')
recommend = request.POST.get('recommend')
author_message = request.POST.get('author_message')
# print(title_new)
wiki_title = get_object_or_404(TitleTree, id=title_id)
wiki_title.name = title_new
wiki_title.save()
# print(wiki_title)
tags_new = request.POST.getlist('tags')
tags_new = Tag.objects.filter(id__in=tags_new)
# print(tags_new)
if WiKiContent.objects.filter(title__id=title_id):
wiki_content = WiKiContent.objects.get(title__id=title_id)
wiki_content.title = wiki_title
wiki_content.content = content
wiki_content.tags = tags_new
wiki_content.recommend = int(recommend)
wiki_content.author_message = author_message
wiki_content.updated_user = request.user
wiki_content.save()
else:
# print('文章不存在,新建')
wiki_content = WiKiContent.objects.create(
title=wiki_title,
content=content,
# tags=tags_new, # 直接在这儿使用会报错
created_user=request.user,
)
wiki_content.tags = tags_new
wiki_content.save()
return redirect(reverse("wiki:wiki_content_backend", kwargs={'title_id': title_id}))
上传图片视图
from django.core.files.base import ContentFile
# @csrf_exempt
def upload_image(request):
print(request.POST)
"""
<QueryDict: {'csrfmiddlewaretoken': ['8gtiXSn7Lz0UFrRt9kdN3BPFHMEVvJb75qQchYfb7MfK1PEIJ42tSmBltWlqG8AE', '8gtiXSn7Lz0UFrRt9kdN3BPFHMEVvJb75qQchYfb7MfK1PEIJ42tSmBltWlqG8AE']}>
"""
print(request.FILES)
"""
<MultiValueDict: {'editormd-image-file': [<InMemoryUploadedFile: Markdown.png (image/png)>]}>
"""
image = request.FILES.get('editormd-image-file', None)
# 将上传的图片绑定到标题,因为它是先创建保存数据库的,如果绑定到正文,则编辑不存在的正文时,会出现模型找不到的情况
wiki_title = get_object_or_404(TitleTree, id=request.GET.get('wiki_title_id'))
if image:
wiki_content_image = WiKiContentImage(
title=image.name,
image=image,
wiki=wiki_title,
created_user=request.user
)
wiki_content_image.save()
image_url = wiki_content_image.image.url
res = {
'success': 1,
'message': '图片上传成功',
'url': image_url
}
else:
res = {
'success': 0,
'message': '图片上传失败',
}
return HttpResponse(json.dumps(res), content_type="text/html")
# 会出错Resource interpreted as Document but transferred with MIME type application/json
# return HttpResponse(json.dumps(res), content_type="application/json")
如果想屏幕CSRF,则可以在视图中添加csrf_exempt
装饰器
路由
url(r'^upload_image/', upload_image, name='upload_image'),
编辑模板
截取一部分代码
<link rel="stylesheet" href="{% static 'editor.md/css/editormd.min.css' %}" />
<div class="form-group">
<label>WiKi正文</label>
<div id="wiki_edit_content_md">
<!--添加Markdown编辑器-->
<textarea name="content"
placeholder="输入WiKi内容">{{ wiki_content.content|safe }}</textarea>
</div>
<p><div class="text-warning"><small></small></div></p>
</div>
<!-- 在HTML中加载JS:顺序为jQuery,editormd.min.js -->
<script src="{% static 'editor.md/editormd.min.js' %}"></script>
<script type="text/javascript">
$(function() {
let editor = editormd("wiki_edit_content_md", {
path: "{% static 'editor.md/lib/' %}", // Autoload modules mode, codemirror, marked... dependents libs path
// width : "1000px", //设置宽度
placeholder: "请输入WiKi内容 ...", // 输入框提示文字
height: 600,
syncScrolling: "single",
saveHTMLToTextarea : true, //注意:这个配置,方便post提交表单,关乎后端是否可以获取到值
watch : false,
tocm: true, // Using [TOCM]
// imageUpload参数在console/markdown_editor/plugins/image-dialog/image-dialog.js文件中进行if判断
// 利用其传参特性将csrf_token传入image-dialog.js文件进行form表单生成
imageUpload: "true",
imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
imageUploadURL: "{% url 'wiki:upload_image' %}?wiki_title_id={{ title_id }}",
imageCsrfToken: "{% csrf_token %}",
/*
{
success : 0 | 1, // 0 表示上传失败,1 表示上传成功
message : "提示的信息,上传成功或上传失败及错误信息等。",
url : "远程图片地址" //上传成功时才返回,就是图片的访问地址
}
*/
});
/*
// or
var editor = editormd({
id : "editormd",
path : "../lib/"
});
*/
});
</script>
可以添加图片描述,图片链接是点击这个图片跳转的url
修改editor.md添加csfr_token支持
编辑 static\editor.md\plugins\image-dialog\image-dialog.js , 修改dialogContent
,添加settings.imageCsrfToken
var dialogContent = ( (settings.imageUpload) ? "<form action=\"" + action +"\" target=\"" + iframeName + "\" method=\"post\" enctype=\"multipart/form-data\" class=\"" + classPrefix + "form\">" : "<div class=\"" + classPrefix + "form\">" ) +
( (settings.imageUpload) ? "<iframe name=\"" + iframeName + "\" id=\"" + iframeName + "\" guid=\"" + guid + "\"></iframe>" : "" ) +
"<label>" + imageLang.url + "</label>" +
"<input type=\"text\" data-url />" + (function(){
return (settings.imageUpload) ? "<div class=\"" + classPrefix + "file-input\">" +
"<input type=\"file\" name=\"" + classPrefix + "image-file\" accept=\"image/*\" />" +
settings.imageCsrfToken + //添加csrf
"<input type=\"submit\" value=\"" + imageLang.uploadButton + "\" />" +
"</div>" : "";
})() +
"<br/>" +
"<label>" + imageLang.alt + "</label>" +
"<input type=\"text\" value=\"" + selection + "\" data-alt />" +
"<br/>" +
"<label>" + imageLang.link + "</label>" +
"<input type=\"text\" value=\"http://\" data-link />" +
"<br/>" +
settings.imageCsrfToken + //添加csrf
( (settings.imageUpload) ? "</form>" : "</div>");
渲染模板
部分代码
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/vs.min.css">
<p id="id_wiki_content">{{ wiki_content.content }}</p>
<script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/1.8.6/showdown.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
<script type="text/javascript">
$(document).ready(() => {
var src = $('#id_wiki_content').text()
var converter = new showdown.Converter();
var html = converter.makeHtml(src);
$('#id_wiki_content').html(html);
hljs.initHighlightingOnLoad();
})
</script>
网友评论