安装
pip install django-ckeditor
- 添加
ckeditor
,ckeditor_uploader
到settings.py的INSTALLED_APPS
中
配置
- 文件上传配置:
- 配置
MEDIA_URL
和MEDIA_ROOT
, 上传路径的根目录就是以MEDIA_ROOT
- 设置
CKEDITOR_UPLOAD_PATH = "uploads/"
, 上传路径{{MEDIA_ROOT}}uploads
- 文件名修改(可以不用)
- utils.py定义一个函数
# utils.py
def get_filename(filename):
return filename.upper()
- settings.py中配置
# settings.py
CKEDITOR_FILENAME_GENERATOR = 'utils.get_filename'
- 图片处理配置
# settings.py
CKEDITOR_IMAGE_BACKEND = "pillow"
IMAGE_QUALITY = 40 # 缩略图质量
THUMBNAIL_SIZE = (300, 300) # 缩略图大小
使用(官方样例)
models.py
from django.db import models
from ckeditor.fields import RichTextField
from ckeditor_uploader.fields import RichTextUploadingField
class ExampleModel(models.Model):
content = RichTextUploadingField()
class ExampleNonUploadModel(models.Model):
content = RichTextField()
在admin中调用
admin.py
from django.contrib import admin
from . import models
admin.site.register(models.ExampleModel)
admin.site.register(models.ExampleNonUploadModel)
- 也可用
widget
重写TextField
from django.contrib import admin
from django.db import models
from ckeditor.widgets import CKEditorWidget
@admin.register(Articles)
class ArticlesAdmin(admin.ModelAdmin):
formfield_overrides = {models.TextField: {'widget': CKEditorWidget()}}
页面中配置
forms.py
from django import forms
from ckeditor.fields import RichTextFormField
class CkEditorForm(forms.Form):
content = RichTextFormField()
- html
<form method="post" action="./">
{% csrf_token %}
{{ form.media }}
{{ form.as_p }}
<p><input type="submit" value="post"></p>
</form>
自定义配置
settings.py
CKEDITOR_CONFIGS = {
'default': {
'toolbar': 'full',
'height': 300,
'width': 300,
},
'forum-post': {
'toolbar': 'Custom',
'toolbar_Custom': [
['Bold', 'Italic', 'Underline'],
['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],
['Link', 'Unlink'],
['RemoveFormat', 'Source']
]
}
}
- 使用不同的配置
text = RichTextField(
config_name='forum-post',
# CKEDITOR.config.extraPlugins:
extra_plugins=['someplugin'],
# CKEDITOR.plugins.addExternal(...)
external_plugin_resources=[(
'someplugin',
'/static/.../path-to-someplugin/',
'plugin.js',
)],
)
文件上传选项:
CKEDITOR_UPLOAD_SLUGIFY_FILENAME # 文件别名
"""ckeditor_uploader.views.get_upload_filename
if (getattr(settings, 'CKEDITOR_UPLOAD_SLUGIFY_FILENAME', True) and
not hasattr(settings, 'CKEDITOR_FILENAME_GENERATOR')):
upload_name = utils.slugify_filename(upload_name)
"""
CKEDITOR_RESTRICT_BY_USER # 设置为True, 上传的目录为<username>的文件夹
"""ckeditor_uploader.views
def _get_user_path(user):
user_path = ''
# If CKEDITOR_RESTRICT_BY_USER is True upload file to user specific path.
RESTRICT_BY_USER = getattr(settings, 'CKEDITOR_RESTRICT_BY_USER', False)
if RESTRICT_BY_USER:
.....
"""
CKEDITOR_BROWSE_SHOW_DIRS # 用的是brower/接口, 浏览显示目录(未试)
CKEDITOR_RESTRICT_BY_DATE # 文件上传路径默认时间目录'%Y/%m/%d', 设置False, 可以让其为空
"""ckeditor_uploader.views
def get_upload_filename(upload_name, user):
user_path = _get_user_path(user)
# Generate date based path to put uploaded file.
# If CKEDITOR_RESTRICT_BY_DATE is True upload file to date specific path.
if getattr(settings, 'CKEDITOR_RESTRICT_BY_DATE', True):
date_path = datetime.now().strftime('%Y/%m/%d')
"""
配置样例
按需要增删, 具体看下源码
CKEDITOR_CONFIGS = {
'default': {
'skin': 'moono-lisa',
# 'skin': 'office2013',
'language': 'zh-cn',
'uiColor': '#AADC6E',
'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', 'CodeSnippet', 'CodeSnippetGeshi']},
{'name': 'links', 'items': ['Link', 'Unlink', 'Anchor']},
{'name': 'insert',
'items': ['Image', 'Flash', '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',
'codesnippet',
]),
}
}