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

Configure Django-TinyMCE Component to Support Image Upload

Django's built-in Admin backend is easy to use, and TinyMCE as a rich text editor is also quite handy. Combining the two is convenient when building a blog (of course, blogs might be better suited to Markdown), but the Django-TinyMCE component does not support image upload by default, so we need to implement it ourselves. This article will walk you through implementing this image upload feature step by step. Readers can also apply the same approach to implement other features that need to be integrated with Django. Writing the image upload logic Add the following code in any views.py:

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

Django's built-in Admin backend is easy to use, and TinyMCE as a rich text editor is also quite handy. Combining the two is convenient when building a blog (of course, blogs might be better suited to Markdown), but the Django-TinyMCE component does not support image upload by default, so we need to implement it ourselves. This article will walk you through implementing this image upload feature step by step.

Readers can also apply the same approach to implement other features that need to be integrated with Django.

Writing the Image Upload Logic

Add the following code in any 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': "错误的请求"})

Configuring Routes

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

Configuring tinymce

Since tinymce is a frontend component, it needs to be configured using js.

Add a js file under the static/tinymce/js directory (please create the directory manually if it does not exist). The name can be anything; here I use 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',
});

In this configuration I added some plugins, tweaked the menu bar and toolbar based on the official documentation, and changed the display language to Chinese (the default is English).

Note the images_upload_url inside — this is the route we just configured for the image upload logic.

For TinyMCE configuration, you can refer to the official documentation: https://www.tiny.cloud/docs/demo/basic-example/

Configuring in admin

Finally, we need to configure the custom js in the admin that uses TinyMCE for the previous configuration to take effect.

Sample code is as follows; just configure it according to your actual 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'
        ]

Testing

With the configuration above, you're done. It should work now — open the admin backend and give it a try where there are tinymce fields~

Looks OK~

Update on December 7, 2021 16:51:36

After uploading images, when you reopen a saved article you'll find that the image links have all become relative links. At this point you need to configure TinyMCE to use absolute paths.

Reference: https://blog.csdn.net/huffmans/article/details/84381481

Add a line convert_urls :false, // 存储URL的原始值 in the previous static/tinymce/js, and that should do it.

References

Welcome to Discuss

I've compiled a series of technical articles and materials. Reply with linux, flutter, c#, netcore, android, kotlin, java, python, etc. in the backend of the WeChat official account "Programming Lab" to get related technical articles and materials. If you have any questions, you can also leave a message in the official account backend~

_EOF_

Configure Django-TinyMCE Component to Support Image Upload

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

相关文章

Django全文检索实现:HayStack-+-Whoosh-+-Jieba

涉及到的工具 haystack是django的开源搜索框架,该框架支持**Solr**, Elasticsearch, Whoosh, **Xapian搜索引擎,不用更改代码,直接切换引擎,减少代码量。 搜索引擎使用Whoosh,这是一个由纯Python实现的全文搜索引擎,没有二进制文件等,比较小巧,配置比较简单,当然性能自然略低。 中文分词Jieba,由于Whoosh自带的是英文分词,对中文的分

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

Django项目引入NPM和gulp管理前端资源

前言 之前写了一篇《Asp-Net-Core开发笔记:使用NPM和gulp管理前端静态文件》,现在又来用Django开发项目了,之前我搞了一个Django的快速开发脚手架「DjangoStarter」,正好给升级一下~ 关于npm和gulp我就不多重复了,之前那篇文章都写了,直接上操作 安装依赖 安装依赖的操作跟上一篇文章是一样的,不过我这里直接提供package.json文件,复制到项目根目录里

2022-04-02 · Django · 约 1 分钟

Django数据库性能优化之使用Python集合操作

前言 最近有个新需求: 人员基础信息(记作人员A),10w 某种类型的人员信息(记作人员B),1000 要求在后台上(Django Admin)分别展示:已录入A的人员B列表、未录入的人员B列表 团队的DBA提议使用视图可以解决这个问题(不愧是搞数据库的) PS:起先我觉得Django的Model是直接管理数据库表的,使用Model来映射数据库模型怕是有一定的麻烦,不过查了一下资料发现并不会~ 只

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

讨论

共 0 条

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

加载评论中…