从 ckeditor_uploader.fields 导入 RichTextUploadingField

From ckeditor_uploader.fields import RichTextUploadingField

从 pip 安装 CKEditor 后,我尝试从模型导入 CKEditor,但它一直给我 ImportError cannot import name get_default_renderer

我按照CKEditor的文档仔细看了之后,还是报错。是我的Django 1.10版本的问题还是彻底的5.6.1版本?有人可以给我指路吗?

models.py

from django.db import models
from django.conf import settings
from django.utils import timezone
from ckeditor_uploader.fields import RichTextUploadingField

# Create your models here.

class Post(models.Model):
    author = models.ForeignKey('auth.User', on_delete= models.CASCADE)
    title = models.CharField(max_length=200)
    text = models.RichTextUploadingField()
    image = models.ImageField()
    created_date = models.DateTimeField(default=timezone.now)
    published_date = models.DateTimeField(blank= True, null = True)

views.py

from django.shortcuts import render, get_object_or_404,  redirect
from django.utils import timezone
from .models import Post
from .forms import CommentForm
# Create your views here.

def post_list(request):
  posts =   Post.objects.filter(published_date__lte=timezone.now()).order_by('-published_date')
return render(request, 'blog/post_list.html', {'posts':posts })

def post_detail(request, pk):
    post = get_object_or_404(Post, pk=pk)
if request.method == 'POST':
    form = CommentForm(request.POST)
    if form.is_valid():
        comment = form.save(commit=False)
        comment.post = post
        comment.save()
        return redirect('blog:post_detail', pk=post.pk)
else:
    form = CommentForm()
return render(request, 'blog/post_detail.html', {'post':post, 'form':form }, )

settings.py

INSTALLED_APPS = [
  'app',
  'cart',
  'orders',
  'blog',
  'ckeditor_uploader',
  # Add your apps here to enable them
  'django.contrib.admin',
  'django.contrib.auth',
  'django.contrib.contenttypes',
  'django.contrib.sessions',
  'django.contrib.messages',
  'django.contrib.staticfiles',
]

CKEDITOR_JQUERY_URL = 'https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js'

CKEDITOR_UPLOAD_PATH = 'uploads/'

CKEDITOR_IMAGE_BACKEND = 'pillow'

#CKEDITOR_CONFIGS = {
#    'default':{
#        'toolbar': None,
#        }
#    }

urls.py

from django.conf.urls import url
import django.contrib.auth.views
from django.conf.urls import include
from django.contrib import admin
from django.conf.urls.static import static
from django.conf import settings
# admin.autodiscover()

urlpatterns = [
   url(r'^admin/', admin.site.urls),
   url(r'^cart', include('cart.urls')),
   url(r'^orders', include('orders.urls')),
   url(r'^', include('app.urls')),
   url(r'^blog/', include('blog.urls')),
   url(r'^ckeditor/', include('ckeditor_uploader.urls')),
]

if settings.DEBUG:
   urlpatterns += static(settings.MEDIA_URL,  document_root=settings.MEDIA_ROOT)

错误页面

ImportError: cannot import name 'get_default_renderer'
Unhandled exception in thread started by <function check_errors.  <locals>.wrapper at 0x0421B4F8>
 Traceback (most recent call last):
 File "C:\Users\stylop\AppData\Local\Programs\Python\Python36-32\lib\site-    packages\django\utils\autoreload.py", line 226, in wrapper
 fn(*args, **kwargs)
 File "C:\Users\stylop\AppData\Local\Programs\Python\Python36-32\lib\site-   packages\django\core\management\commands\runserver.py", line 113, in inner_run
 autoreload.raise_last_exception()
 File "C:\Users\stylop\AppData\Local\Programs\Python\Python36-32\lib\site- packages\django\utils\autoreload.py", line 249, in raise_last_exception
 six.reraise(*_exception)
 File "C:\Users\stylop\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\utils\six.py", line 685, in reraise
 raise value.with_traceback(tb)
 File "C:\Users\stylop\AppData\Local\Programs\Python\Python36-32\lib\site- packages\django\utils\autoreload.py", line 226, in wrapper
fn(*args, **kwargs)
File "C:\Users\stylop\AppData\Local\Programs\Python\Python36-32\lib\site-  packages\django\__init__.py", line 27, in setup
apps.populate(settings.INSTALLED_APPS)
File "C:\Users\stylop\AppData\Local\Programs\Python\Python36-32\lib\site- packages\django\apps\registry.py", line 108, in populate
app_config.import_models(all_models)
File "C:\Users\stylop\AppData\Local\Programs\Python\Python36-32\lib\site- packages\django\apps\config.py", line 199, in import_models
self.models_module = import_module(models_module_name)
File "C:\Users\stylop\AppData\Local\Programs\Python\Python36-32 \lib\importlib\__init__.py", line 126, in import_module
 return _bootstrap._gcd_import(name[level:], package, level)
 File "<frozen importlib._bootstrap>", line 978, in _gcd_import
 File "<frozen importlib._bootstrap>", line 961, in _find_and_load
 File "<frozen importlib._bootstrap>", line 950, in _find_and_load_unlocked
 File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
 File "<frozen importlib._bootstrap_external>", line 678, in exec_module
 File "<frozen importlib._bootstrap>", line 205, in _call_with_frames_removed
 File "C:\Users\stylop\source\repos\alfiez\alfiez\blog\models.py", line 4, in <module>
from ckeditor_uploader.fields import RichTextUploadingField
 File "C:\Users\stylop\AppData\Local\Programs\Python\Python36-32\lib\site-packages\ckeditor_uploader\fields.py", line 3, in <module>
 from ckeditor import fields
 File "C:\Users\stylop\AppData\Local\Programs\Python\Python36-32\lib\site-packages\ckeditor\fields.py", line 6, in <module>
 from .widgets import CKEditorWidget
 File "C:\Users\stylop\AppData\Local\Programs\Python\Python36-32\lib\site- packages\ckeditor\widgets.py", line 12, in <module>
 from django.forms.widgets import get_default_renderer
 ImportError: cannot import name 'get_default_renderer'

如果您想要的只是一个简单的所见即所得编辑器。 django-ckeditor 非常适合你。

pip install django-ckeditor

ckeditor 添加到 settings.py

中的 INSTALLED_APPS

运行 collectstatic 管理命令:$ ./manage.py collectstatic. 这会将静态 CKEditor 所需的媒体资源复制到 STATIC_ROOT 设置给定的目录中

在你的 models.py 中导入 from ckeditor.fields import RichTextField 并像这样直接使用它

class Foo(models.Model):
   content = RichTextField()

也导入你的 forms.py from ckeditor.fields import RichTextFormField 并像

一样直接使用它
class FooForm(forms.ModelForm):
    class Meta:
          model = Foo
          fields = ['content']
          widgets = {
             'content': RichTextFormField(),
          }

你应该有这样的东西 如需更多配置,您可以将其添加到您的 settings.py 并根据您的需要进行配置

# CKEditor Configuration Settings

CKEDITOR_CONFIGS = {
    'default': {
        # 'toolbar': 'Custom',
        'width': '461px',
        'height': 'auto',
        # 'toolbar_Custom': [
        #     ['Bold', 'Italic', 'Underline'],
        #     ['NumberedList', 'BulletedList'],
        # ],
    }
}

设置CKEditor和工具上传图片

  1. pip install django-ckeditor

  2. 在文件 setting.py

    中添加 ckeditor 和 ckeditor_uploader
    INSTALLED_APPS = [
        ...
        'ckeditor',
        'ckeditor_uploader',
        ...
    ]
    
  3. 在文件下方添加代码setting.py

    CKEDITOR_CONFIGS = {
    'portal_config': {
        # 'skin': 'moono',
        # 'skin': 'office2013',
        'toolbar_Basic': [
            ['Source', '-', 'Bold', 'Italic']
        ],
        'toolbar_YourCustomToolbarConfig': [
            {'name': 'document', 'items': [
                'Source', '-', 'Save', 'NewPage', 'Preview', 'Print', '-', 'Templates'
            ]},
            {'name': 'clipboard', 'items': [
                'Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo'
            ]},
            {'name': 'editing', 'items': ['Find', 'Replace', '-', 'SelectAll']},
            {'name': 'forms',
             'items': [
                 'Form', 'Checkbox', 'Radio', 'TextField', 'Textarea',
                 'Select', 'Button', 'ImageButton', 'HiddenField'
             ]},
            '/',
            {'name': 'basicstyles',
             'items': [
                 'Bold', 'Italic', 'Underline', 'Strike', 'Subscript',
                 'Superscript', '-', 'RemoveFormat'
             ]},
            {'name': 'paragraph',
             'items': [
                 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent',
                 '-', 'Blockquote', 'CreateDiv', '-', 'JustifyLeft',
                 'JustifyCenter', 'JustifyRight', 'JustifyBlock', '-',
                 'BidiLtr', 'BidiRtl', 'Language'
             ]},
            {'name': 'links', 'items': ['Link', 'Unlink', 'Anchor']},
            {'name': 'insert',
             'items': [
                 'Image', 'Table', 'HorizontalRule',
                 'Smiley', 'SpecialChar', 'PageBreak', 'Iframe'
             ]},
            '/',
            {'name': 'styles', 'items': ['Styles', 'Format', 'Font', 'FontSize']},
            {'name': 'colors', 'items': ['TextColor', 'BGColor']},
            {'name': 'tools', 'items': ['Maximize', 'ShowBlocks']},
            {'name': 'about', 'items': ['About']},
            '/',  # put this to force next toolbar on new line
            {'name': 'yourcustomtools', 'items': [
                # put the name of your editor.ui.addButton here
                'Preview',
                'Maximize',
    
            ]},
        ],
        'toolbar': 'YourCustomToolbarConfig',  # put selected toolbar config here
        # 'toolbarGroups': [{ 'name': 'document', 'groups': [ 'mode', 'document', 'doctools' ] }],
        # 'height': 291,
        # 'width': '100%',
        # 'filebrowserWindowHeight': 725,
        # 'filebrowserWindowWidth': 940,
        # 'toolbarCanCollapse': True,
        # 'mathJaxLib': '//cdn.mathjax.org/mathjax/2.2-latest/MathJax.js?config=TeX-AMS_HTML',
        'tabSpaces': 4,
        'extraPlugins': ','.join([
            'uploadimage',  # the upload image feature
            # your extra plugins here
            'div',
            'autolink',
            'autoembed',
            'embedsemantic',
            'autogrow',
            # 'devtools',
            'widget',
            'lineutils',
            'clipboard',
            'dialog',
            'dialogui',
            'elementspath'
        ]),
        }
    }
    
  4. 模型

    from ckeditor_uploader.fields import RichTextUploadingField
    
    
    class Article(models.Model):
     body = RichTextUploadingField(config_name='portal_config')