返回文章列表文章索引阅读全文
STARBLOG / 阅读手记
Django

配置Django-TinyMCE组件支持上传图片功能

Django自带的Admin后台,好用,TinyMCE作为富文本编辑器,也蛮好用的,这两者结合起来在做博客的时候很方便(当然博客可能更适合用Markdown来写),但是Django-TinyMCE这个组件默认没有图片上传功能的,需要我们自己实现,本文将一步步带大家实现这个图片上传功能。 读者也可以举一反三实现其他需要和Django结合的功能。 编写上传图片逻辑 在任一views.py里添加代码:

曦远 (DealiAxy)约 11 分钟
目录8 个章节

Django自带的Admin后台,好用,TinyMCE作为富文本编辑器,也蛮好用的,这两者结合起来在做博客的时候很方便(当然博客可能更适合用Markdown来写),但是Django-TinyMCE这个组件默认没有图片上传功能的,需要我们自己实现,本文将一步步带大家实现这个图片上传功能。

读者也可以举一反三实现其他需要和Django结合的功能。

编写上传图片逻辑

在任一views.py里添加代码:

import os

from django.conf import settings
from django.http import JsonResponse
from django.utils import timezone
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def upload_image(request):
    if request.method == "POST":
        file_obj = request.FILES['file']
        file_name_suffix = file_obj.name.split(".")[-1]
        if file_name_suffix not in ["jpg", "png", "gif", "jpeg", ]:
            return JsonResponse({"message": "错误的文件格式"})

        upload_time = timezone.now()
        path = os.path.join(
            settings.MEDIA_ROOT,
            'tinymce',
            str(upload_time.year),
            str(upload_time.month),
            str(upload_time.day)
        )
        # 如果没有这个路径则创建
        if not os.path.exists(path):
            os.makedirs(path)

        file_path = os.path.join(path, file_obj.name)

        file_url = f'{settings.MEDIA_URL}tinymce/{upload_time.year}/{upload_time.month}/{upload_time.day}/{file_obj.name}'

        if os.path.exists(file_path):
            return JsonResponse({
                "message": "文件已存在",
                'location': file_url
            })

        with open(file_path, 'wb+') as f:
            for chunk in file_obj.chunks():
                f.write(chunk)

        return JsonResponse({
            'message': '上传图片成功',
            'location': file_url
        })
    return JsonResponse({'detail': "错误的请求"})

配置路由

urlpatterns = [
    # 上传图片
    path('upload_image/', views.upload_image),
    # tinymce 编辑器
    path('tinymce/', include('tinymce.urls')),
]

配置tinymce

由于tinymce是一个前端组件,所以需要使用js来配置。

在static/tinymce/js目录下添加一个js文件(目录不存在请手动创建),名字随意,我这里是textareas.js:

tinymce.init({
    selector: 'textarea',  // change this value according to your HTML
    images_upload_url: '/upload_image/', // Django路由中图片上传地址
    height: 500,
    plugins: [
        'advlist autolink lists link image charmap print preview anchor',
        'searchreplace visualblocks code fullscreen',
        'insertdatetime media table paste code help wordcount'
    ],
    menubar: 'favs file edit view insert format tools table help',
    toolbar: 'undo redo | formatselect | ' +
        'bold italic backcolor | alignleft aligncenter ' +
        'alignright alignjustify | bullist numlist outdent indent | ' +
        'code image | ' +
        'removeformat | help',
    language: 'zh_CN',
});

这段配置代码里面我加了一些插件,参照官方文档改了一下菜单栏和工具栏,并且把显示语言改成中文(默认是英文)。

注意里面的images_upload_url,这个是刚才配置了上传图片逻辑的路由。

关于TinyMCE的配置可以参考官方文档:https://www.tiny.cloud/docs/demo/basic-example/

在admin中配置

最后,我们需要在用到TinyMCE的admin中配置自定义的js,才能使前面的配置生效。

参考代码如下,按照自己的实际model配置就行了。

@admin.register(models.Activity)
class ActivityAdmin(admin.ModelAdmin):
    list_display = ['pk', 'title']

    class Media:
        js = [
            'tinymce/jquery.tinymce.min.js',
            'tinymce/tinymce.min.js',
            'tinymce/js/textareas.js'
        ]

测试

经过上面的配置就完成了,现在已经可以了,打开admin后台有tinymce字段的地方试一下呗~

效果OK~

2021年12月7日 16:51:36 更新

上传图片之后,保存起来的文章重新打开会发现图片链接都变成了相对链接,这时候得配置让TinyMCE去使用绝对路径。

参考:https://blog.csdn.net/huffmans/article/details/84381481

在之前的static/tinymce/js里面加一行convert_urls :false, // 存储URL的原始值,就可以了

参考资料

欢迎交流

我整理了一系列的技术文章和资料,在公众号「程序设计实验室」后台回复 linux、flutter、c#、netcore、android、kotlin、java、python 等可获取相关技术文章和资料,同时有任何问题都可以在公众号后台留言~

_EOF_

配置Django-TinyMCE组件支持上传图片功能

本文作者:
程序设计实验室
版权声明:
本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

相关文章

轻量级消息队列Django-Q轻度体验

前言 最近做的这个项目(基于Django),需要做个功能,实现定时采集车辆定位。 这让我想起来几年前那个OneCat项目,当时我用的是Celery这个很重的组件 Celery实在是太重了,后来我做公众号采集平台的时候,又接触了Django-RQ和Django-Q这俩,前者是对RQ的封装,让RQ和Django更好的结合在一起;后者是一个全新的「多进程任务队列」组件,相比起celery很轻量,当时使用

2022-08-31 · Django · 约 1 分钟

Django的信号机制入门

概念 django自带一套信号机制来帮助我们在框架的不同位置之间传递信息。也就是说,当某一事件发生时,信号系统可以允许一个或多个发送者(senders)将通知或信号(signals)发送给一组接受者(receivers)。 (感觉就很像Qt的信号与槽机制) 信号系统包含以下三要素: 发送者-信号的发出方 信号-信号本身 接收者-信号的接受者 Django内置了一整套信号,下面是一些比较常用的: 在

2022-08-26 · Django · 约 1 分钟

讨论

共 0 条

良言一句三冬暖,恶语伤人六月寒。

加载评论中…