1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > django框架加入simditor富文本编辑器 使用mako进行渲染

django框架加入simditor富文本编辑器 使用mako进行渲染

时间:2024-03-06 09:28:08

相关推荐

django框架加入simditor富文本编辑器 使用mako进行渲染

1.安装依赖

django-simditor==0.0.15

2.配置

INSTALLED_APPS += ('simditor',)SIMDITOR_TOOLBAR = ['title', 'bold', 'italic', 'underline', 'strikethrough', 'fontScale','color', '|', 'ol', 'ul', 'blockquote', 'table', '|', 'link', 'image','hr', '|', 'indent', 'outdent', 'alignment', # '|', 'markdown']SIMDITOR_UPLOAD_PATH = 'uploads/'SIMDITOR_IMAGE_BACKEND = 'pillow'# 图片上传的urlSIMDITOR_CONFIGS = {'toolbar': SIMDITOR_TOOLBAR,'upload': {'url': SITE_URL + '/simditor/upload/','fileKey': 'upload','image_size': 1024 * 1024 * 4 # max image size 4MB},'emoji': {'imagePath': '/static/simditor/images/emoji/'}}

3.生成simditor编辑器form的代码

# -*- coding: utf-8from __future__ import unicode_literals, absolute_importfrom django.conf.urls import include, urlfrom simditor import utils, image_processingfrom .widgets import SimditorWidgetimport osfrom datetime import datetimefrom django.conf import settingsfrom django.core.files.storage import default_storagefrom django.http import JsonResponsefrom django.views import genericfrom django.views.decorators.csrf import csrf_exempt# from . import utils, image_processingclass SimditorEditor():"""Editors should inherit from this. See wiki.editors for examples."""# The editor id can be used for conditional testing. If you write your# own editor class, you can use the same editor_id as some editoreditor_id = 'simditor'def get_admin_widget(self):return SimditorWidget()def get_widget(self, instance=None):return SimditorWidget()def get_urls(self):return [url(r'^simditor/', include('simditor.urls'))]class AdminMedia:css = {'all': ('wiki/simditor/styles/simditor.css','wiki/simditor/styles/simditor-markdown.css',)}js = ('wiki/simditor/scripts/jquery.min.js','wiki/simditor/scripts/module.js','wiki/simditor/scripts/uploader.js','wiki/simditor/scripts/hotkeys.js','wiki/simditor/scripts/simditor.js','wiki/simditor/scripts/marked.js','wiki/simditor/scripts/to-markdown.js','wiki/simditor/scripts/simditor-markdown.js',)class Media:css = {'all': ('wiki/simditor/styles/simditor.css','wiki/simditor/styles/simditor-markdown.css',)}js = ('wiki/simditor/scripts/jquery.min.js','wiki/simditor/scripts/module.js','wiki/simditor/scripts/uploader.js','wiki/simditor/scripts/hotkeys.js','wiki/simditor/scripts/simditor.js','wiki/simditor/scripts/marked.js','wiki/simditor/scripts/to-markdown.js','wiki/simditor/scripts/simditor-markdown.js',)def get_upload_filename(upload_name):# Generate date based path to put uploaded file.date_path = datetime.now().strftime('%Y/%m/%d')# Complete upload path (upload_path + date_path).upload_path = os.path.join(settings.SIMDITOR_UPLOAD_PATH, date_path)if getattr(settings, 'SIMDITOR_UPLOAD_SLUGIFY_FILENAME', True):upload_name = utils.slugify_filename(upload_name)return default_storage.get_available_name(os.path.join(upload_path, upload_name))def upload_handler(request):files = request.FILESupload_config = settings.SIMDITOR_CONFIGS.get('upload', {'fileKey': 'upload'})filekey = upload_config.get('fileKey', 'upload')uploaded_file = files.get(filekey)if not uploaded_file:retdata = {'file_path': '', 'success': False,'msg': '图片上传失败,无法获取到图片对象!'}return JsonResponse(retdata)image_size = upload_config.get('image_size')if image_size and uploaded_file.size > image_size:retdata = {'file_path': '', 'success': False,'msg': '上传失败,已超出图片最大限制!'}return JsonResponse(retdata)backend = image_processing.get_backend()if not getattr(settings, 'SIMDITOR_ALLOW_NONIMAGE_FILES', True):try:backend.image_verify(uploaded_file)except utils.NotAnImageException:retdata = {'file_path': '', 'success': False,'msg': '图片格式错误!'}return JsonResponse(retdata)filename = get_upload_filename(uploaded_file.name)saved_path = default_storage.save(filename, uploaded_file)url = utils.get_media_url(saved_path)is_api = settings.SIMDITOR_CONFIGS.get('is_api', False)url = request.META.get('HTTP_ORIGIN') + url if is_api else urlretdata = {'file_path': url, 'success': True, 'msg': '上传成功!'}return JsonResponse(retdata)class ImageUploadView(generic.View):"""ImageUploadView."""http_method_names = ['post']def post(self, request, **kwargs):"""Post."""return upload_handler(request)UPLOAD = csrf_exempt(ImageUploadView.as_view())

这里有一个坑,由于SimditorWidget()从依赖中引入不识别,我解决的办法:将这个内容所在的文件从依赖中拷贝出来,直接从这个文件引入

widgets.py

"""simditor widgets."""from __future__ import absolute_importfrom django import formsfrom django.conf import settingsfrom django.core.exceptions import ImproperlyConfiguredfrom django.core.serializers.json import DjangoJSONEncoderfrom django.template.loader import render_to_stringfrom django.utils.encoding import force_textfrom django.utils.safestring import mark_safefrom django.utils.html import conditional_escapefrom django.utils.functional import Promisefrom conf.default import SITE_URLtry:# Django >=2.1from django.forms.widgets import get_default_rendererIS_NEW_WIDGET = Trueexcept ImportError:IS_NEW_WIDGET = Falsetry:# Django >=1.7from django.forms.utils import flatattexcept ImportError:# Django <1.7from django.forms.util import flatatt # pylint disable=E0611, E0401class LazyEncoder(DjangoJSONEncoder):"""LazyEncoder."""# pylint disable=E0202def default(self, obj):if isinstance(obj, Promise):return force_text(obj)return super(LazyEncoder, self).default(obj)JSON_ENCODE = LazyEncoder().encodeFULL_TOOLBAR = ['title', 'bold', 'italic', 'underline', 'strikethrough', 'fontScale','color', '|', 'ol', 'ul', 'blockquote', 'code', 'table', '|', 'link','image', 'hr', '|', 'indent', 'outdent', 'alignment', 'checklist','markdown', 'fullscreen']DEFAULT_TOOLBAR = ['title', 'bold', 'italic', 'underline', 'strikethrough', 'fontScale','color', '|', 'ol', 'ul', 'blockquote', 'table', '|', 'link', 'image','hr', '|', 'indent', 'outdent', 'alignment', # '|', 'markdown']SIMDITOR_UPLOAD_PATH = 'uploads/'SIMDITOR_IMAGE_BACKEND = 'pillow'# 我的理解是前端的上传图片请求配置DEFAULT_CONFIG = {'toolbar': DEFAULT_TOOLBAR,'cleanPaste': True,'tabIndent': True,'pasteImage': True,'upload': {'url': SITE_URL + '/simditor/upload/','fileKey': 'upload','image_size': 1024 * 1024 * 4 # max image size 4MB},}class SimditorWidget(forms.Textarea):"""Widget providing Simditor for Rich Text Editing.absSupports direct image uploads and embed."""class Media:"""Media."""css_list = ['simditor/styles/simditor.css']if 'emoji' in settings.SIMDITOR_TOOLBAR:css_list.append('simditor/styles/simditor-emoji.css')if 'fullscreen' in settings.SIMDITOR_TOOLBAR:css_list.append('simditor/styles/simditor-fullscreen.min.css')if 'checklist' in settings.SIMDITOR_TOOLBAR:css_list.append('simditor/styles/simditor-checklist.min.css')if 'markdown' in settings.SIMDITOR_TOOLBAR:css_list.append('simditor/styles/simditor-markdown.min.css')css = {'all': tuple(settings.STATIC_URL + url for url in css_list)}jquery_list = ['simditor/scripts/jquery.min.js','simditor/scripts/module.min.js','simditor/scripts/hotkeys.min.js','simditor/scripts/uploader.min.js',# 'simditor/scripts/simditor.min.js','simditor/scripts/simditor.js',]if 'fullscreen' in settings.SIMDITOR_TOOLBAR:jquery_list.append('simditor/scripts/simditor-fullscreen.min.js')if 'checklist' in settings.SIMDITOR_TOOLBAR:jquery_list.append('simditor/scripts/simditor-checklist.min.js')if 'markdown' in settings.SIMDITOR_TOOLBAR:jquery_list.append('simditor/scripts/marked.min.js')jquery_list.append('simditor/scripts/to-markdown.min.js')jquery_list.append('simditor/scripts/simditor-markdown.min.js')if 'image' in settings.SIMDITOR_TOOLBAR:jquery_list.append('simditor/scripts/simditor-dropzone.min.js')if 'emoji' in settings.SIMDITOR_TOOLBAR:jquery_list.append('simditor/scripts/simditor-emoji.js')js = tuple(settings.STATIC_URL + url for url in jquery_list)try:js += (settings.STATIC_URL + 'simditor/simditor-init.js',)except AttributeError:raise ImproperlyConfigured("django-simditor requires \SIMDITOR_MEDIA_PREFIX setting. This setting specifies a \URL prefix to the ckeditor JS and CSS media (not \uploaded media). Make sure to use a trailing slash: \SIMDITOR_MEDIA_PREFIX = '/media/simditor/'")def __init__(self, *args, **kwargs):super(SimditorWidget, self).__init__(*args, **kwargs)# Setup config from defaults.self.config = DEFAULT_CONFIG.copy()# Try to get valid config from settings.configs = getattr(settings, 'SIMDITOR_CONFIGS', None)if configs:if isinstance(configs, dict):self.config.update(configs)else:raise ImproperlyConfigured('SIMDITOR_CONFIGS setting must be a dictionary type.')def build_attrs(self, base_attrs, extra_attrs=None, **kwargs):"""Helper function for building an attribute dictionary.This is combination of the same method from Django<=1.10 and Django1.11"""attrs = dict(base_attrs, **kwargs)if extra_attrs:attrs.update(extra_attrs)return attrsdef render(self, name, value, attrs=None, renderer=None):if value is None:value = ''final_attrs = self.build_attrs(self.attrs, attrs, name=name)params = ('simditor/widget.html', {'final_attrs': flatatt(final_attrs),'value': conditional_escape(force_text(value)),'id': final_attrs['id'],'config': JSON_ENCODE(self.config)})if renderer is None and IS_NEW_WIDGET:renderer = get_default_renderer()data = renderer.render(*params) if IS_NEW_WIDGET else render_to_string(*params)return mark_safe(data)

4.form表单部分代码

forms.py文件class CreateForm(forms.Form, SpamProtectionMixin):def __init__(self, request, urlpath_parent, *args, **kwargs):super(CreateForm, self).__init__(*args, **kwargs)# 富文本字段richtext = forms.CharField(label=_('Contents'),required=False,widget=SimditorEditor().get_widget())article.py文件class Create(FormView, ArticleMixin):form_class = forms.CreateFormtemplate_name = "wiki/create.html"

最后一个问题就是上传图片会出的问题:上传需要url路由,不然上传不识别路由报错,导致上传失败

from django.views.decorators.csrf import csrf_exemptfrom .simditor import ImageUploadView # 从simditor.py导入的urlpatterns += [url(r'^simditor/upload', csrf_exempt(ImageUploadView.as_view())),]

这样就可以识别了

效果:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。