django-ckeditor富文本编辑插件:使用RichTextUploadingField在admin后台显示不了富文本框

前言:环境一致是复现代码的前提。
本次实验环境:python 3.7,Django 3.2.21,django-ckeditor 6.3.2

注:请看到末尾

学习到django-ckeditor富文本这一节时,按照步骤:

  1. pip install django-ckeditor

  2. settings.py中配置:

    INSTALLED_APPS = [
        'show',      # 你的App
        'ckeditor',  # 普通富文本框
        'ckeditor_uploader'  # 可以上传文件的富文本框
    ]
    
    MEDIA_URL = "/media/"
    MEDIA_ROOT = BASE_DIR / "media"
    CKEDITOR_UPLOAD_PATH = "article_images"  
    
    CKEDITOR_CONFIGS = {
        'default': {
            'toolbar': 'Full'
        }
    }
    CKEDITOR_ALLOW_NONIMAGE_FILES = False   # 不允许非图片文件上传: 即只能上传图片
    CKEDITOR_BROWSE_SHOW_DIRS = True
    

    别忘了新建文件夹/media/article_images,media与应用文件夹show同级
    在这里插入图片描述

  3. 配置路由(关于总url中富文本编辑器的路由信息,请参考文末进行修正

    # 总urls.py
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('', include('show.urls')),
        # 媒体资源路由
        re_path('media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT}, name='media'),
        # 设置编辑器的路由信息
        path('ckeditor/', include('ckeditor_uploader.urls')),
    ]
    
  4. 更改模型字段

    # show应用的models.py
    class ArticleInfo(models.Model):
        content = RichTextUploadingField(verbose_name='内容')
    
  5. 在admin后台注册编辑文章的入口:

    # show应用的admin.py
    from django.contrib import admin
    from .models import *
    
    @admin.register(ArticleInfo)
    class ArticleInfoAdmin(admin.ModelAdmin):
        list_display = ['content']
    
  6. 数据迁移,创建superuser账户,登录后台,发现content字段并没有变成富文本框(RichTextUploadingField不行 ,但是普通富文本框RichTextField能正常显示,不过我需要的是可以上传文件的前者)
    在这里插入图片描述
    **

解答:

大多数答案都没有标注环境版本,找了很久才找到线索:How to add CkEditor in django
在这里插入图片描述

降低版本: pip install django-ckeditor==6.0.0 成功显示富文本框,并且能成功上传文件

在这里插入图片描述
在这里插入图片描述


在寻找解决方案的过程中,我还做了以下尝试并找到了另一种更复杂的解决方法:
注:原工程有点庞大,为了缩短篇幅,现将django-ckeditor所涉及到的代码单独挑出来做成demo(去掉自定义登录注册等功能

思路:不降低django-ckeditor的版本,使用模型表单

很多答案都提到了表单,反正前端也要做一个文本编辑框让普通用户写博客,何不用模型表单?

  1. 安装django-ckeditor(同上)

  2. settings.py配置(同上)

  3. 定义model(同上)

  4. 定义forms

    from django import forms
    # from ckeditor.widgets import CKEditorWidget  # 普通富文本框
    from ckeditor_uploader.widgets import CKEditorUploadingWidget  # 可以上传文件的富文本框
    from .models import ArticleInfo
    
    class PostAdminForm(forms.ModelForm):
    	# content = forms.CharField(widget=CKEditorWidget())        # 普通富文本框
        content = forms.CharField(widget=CKEditorUploadingWidget()) # 可以上传文件的富文本框
        class Meta:
            model = ArticleInfo
            fields = '__all__'
    
  5. 两个urls (关于总url中富文本编辑器的路由信息,请参考文末进行修正

    # 总urls.py 参考文末进行修改
    ...
    # myapp.urls.py
    urlpatterns = [
        path('h.html', article, name='article'),
    ]
    
  6. views.py

    from django.shortcuts import render
    from .forms import PostAdminForm
    from django.http import HttpResponse
    
    def article(request):
        if request.method == 'POST':
            form = PostAdminForm(data=request.POST)
            if form.is_valid():
                form.save()
                return HttpResponse('提交完了')
        form = PostAdminForm()
        return render(request, 'article.html', locals())
    
  7. article.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>haha</title>
    </head>
    <body>
    
    <form method="post">
            {% csrf_token %}
            {{form.content |safe}}
            {{form.media}}
            <input type="submit" value="Submit">
        </form>
    
    </body>
    </html>
    

    注意加上{{form.media}}根据文档,这句相当于下面手动加载外部富文本框资源。不加载资源无法正常显示

    {% load static %}
    <script type="text/javascript" src="{% static "ckeditor/ckeditor-init.js" %}"></script>
    <script type="text/javascript" src="{% static "ckeditor/ckeditor/ckeditor.js" %}"></script>
    
  8. admin.py

    from django.contrib import admin
    from .forms import *
    from .models import *
    
    @admin.register(ArticleInfo)
    class ArticleInfoAdmin(admin.ModelAdmin):
        list_display = ['content']
        form = PostAdminForm  #注意!! 6.3.2版本下,RichTextUploadingField要在此处指定form才能在后台正常显示 ,而RichTextField不需要指定
        # 如果降低了版本为6.0.0,都不需要指定form
    
    
  9. 数据迁移,创建superuser,登录admin后台,功能一切正常;访问前端界面http://127.0.0.1:8000/h.html,功能正常。
    RichTextField和RichTextUploadingField两者的切换别忘了数据对应跟着迁移。

走的弯路:

由于先实验的普通富文本框,实验成功后,再换为能上传文件的富文本框。切换过程中,忘记将模型表单字段也由widget=CKEditorWidget()更改为widget=CKEditorUploadingWidget(),导致切换后不出现upload按钮
在这里插入图片描述

刚开始没查出原因,参考1参考2,更改config.js文件,添加配置
config.filebrowserImageUploadUrl= "/media/article_images"; 或者
config.filebrowserImageUploadUrl="/media/article_images/&responseType=json"; 都无效
在这里插入图片描述
为了弄清楚config.filebrowserImageUploadUrl的含义和用法,参考官方文档
**
在这里插入图片描述
如果没有设置,就用filebrowserUploadUrl,如果设置了这个参数,upload按钮就会出现

在这里插入图片描述

查看源代码,默认会设置设置这个参数啊(如果确定用的是’ckeditor_uploader’的话)

# ...\venv\Lib\site-packages\ckeditor_uploader\widgets.py
from django.urls import reverse
from ckeditor import widgets

class CKEditorUploadingWidget(widgets.CKEditorWidget):
    def _set_config(self):
        if "filebrowserUploadUrl" not in self.config:
            self.config.setdefault("filebrowserUploadUrl", reverse("ckeditor_upload"))
        if "filebrowserBrowseUrl" not in self.config:
            self.config.setdefault("filebrowserBrowseUrl", reverse("ckeditor_browse"))
        super(CKEditorUploadingWidget, self)._set_config()

更有甚者(Enable Image Upload Button in ckeditor in Python/Django)让我去更改upload按钮的‘hidden’属性。upload按钮在ckeditor面板中隐藏没错,在ckeditor_uploader应该会自动显示出来啊,为什么需要手动更改?除非我用得根本就还是ckeditor(事实证明,确实如此)

查缺补漏:几个路径配置的用法与区别

富文本框不能显示,最先想到的原因是路径问题,检查了几个‘static’路径,更改半天都无效,最后发现这里根本就没用到static路径。。为了加深记忆,做个笔记吧~

STATIC_URL = '/static/'   # 只能识别APP下的static文件夹
STATICFILES_DIRS = [BASE_DIR / 'publicStatic']   # 上面的升级版:资源集合,上线生产过程前需要去掉
STATIC_ROOT = BASE_DIR / 'static'   # 上线生产阶段使用,服务器和项目资源映射,collectstatic命令收集所有的静态资源放这里

# 设置媒体资源的保存路径
MEDIA_URL = "/media/"   # 代表用户通过URL来访问这个本地地址的URL。如本机http://127.0.0.1/, MEDIA_URL设置为"/site_media/",那么通过http://127.0.0.1/site_media/*** 就可以访问相关的上传图片或者其他资源。
MEDIA_ROOT = BASE_DIR / "media"   # 用户上传的文件保存位置

次日更新:来看看我又发现了什么好问题

次日来重新操作一遍上传文件,发现普通用户在前端上传图片报错Incorrect server response.
在这里插入图片描述

把cookie清除了也不行,superuser登录admin后台中上传图片一切正常,但是普通用户前端就是上传不了图片!
参考django ckeditor image upload搞清楚原来默认上传文件有个职员身份限制!搞定!看来上传图片需要用户登录。

等等,我的demo不是为了节省篇幅而把自定义登录注册删了吗?不登陆为什么可以上传?实验一番,发现原来admin后台登录后,直接返回到前端富文本界面,操作此界面的用户还是刚才admin登录的用户! 在views.py的视图函数article中,打印 登录admin后访问前端富文本界面的request.user,和admin logout 后访问前端界面的request.user,验证猜想!

至于昨天为什么没发现错误,是因为我在admin后台登录了具有最高权限的superuser(不存在职员身份限制问题),并且不知道后台登录的superuser可以影响到前端(“不登录”还可以上传文件的问题),而superuser也一直没有logout,歪打正着,一路畅通。今天换成普通用户,就发现问题了。(仔细想想,富文本框中上传的文件属于文章信息表的content字段,文章信息表又和User表有关联,如果是匿名用户,上传的内容属于谁呢?)
在这里插入图片描述

# 总urls.py
...
from django.contrib.auth.decorators import login_required
from django.views.decorators.cache import never_cache
from ckeditor_uploader import views as ckeditor_views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('show.urls')),
    re_path('media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT}, name='media'),
   
    # 设置编辑器的路由信息
    # path('ckeditor/', include('ckeditor_uploader.urls')),
    path('ckeditor/upload/', login_required(ckeditor_views.upload), name='ckeditor_upload'),
    path('ckeditor/browse/', never_cache(login_required(ckeditor_views.browse)), name='ckeditor_browse'),
]
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值