一、DjangoUeditor

1、概述

​ 富文本编辑器,在web开发中可以说是不可缺少的 ,但是django并没有自带富文本编辑器,因此我们需要使用第三方库,这里使用DjangoUeditor。

​ DjangoUeditor是百度开源的在线HTML编辑器,功能非常强大,像表格可以直接拖动调整单元格大小等

2、安装

​ 该库存在bug,需要修改源码文件,因此使用源文件安装

1.新建项目

​ 创建需要使用DjangoUeditor的django项目

2.下载

​ 从github下载源码进行安装: github.com/twz915/Djang,下载后解压,在解压后的文件夹中有一个 DjangoUeditor 文件夹,我们后续需要使用到

3.项目中添加库

  1. 在项目根目录下新建 extra_apps 文件夹
  2. 在 extra_apps 文件夹上依次 右键 >>Mark Directory as>>Sources Root,设置为项目资源文件夹
  3. 将第二步解压出来的文件夹中的 DjangoUeditor 目录拷贝到 extra_apps
  4. 在项目的 settings 中增加以下代码:

python sys.path.insert(0, os.path.join(BASE_DIR, 'extra_apps'))

3.应用

1.settings

        INSTALLED_APPS = [
    # ......

    'DjangoUeditor',
]
      

2.根urls

        urlpatterns = [
    # ......
    path('ueditor/', include('DjangoUeditor.urls')),
]
      

3.UEditorField

​ UEditorField继承自models.TextField,因此可以直接将model里面定义的models.TextField直接改成UEditorField即可。

​ 定义UEditorField时除了可以直接传入models.TextField提供的参数外,还可以传入UEditorField提供的额外的参数来控制UEditorField的外观、上传路径等。

​ UEditorField的参数如下:

  • width,height :编辑器的宽度和高度,以像素为单位。
  • toolbars :配置你想显示的工具栏,取值为mini,normal,full,代表小,一般,全部。如果默认的工具栏的按钮数量不符合您的要求,您可以在settings里面配置自己的显示按钮。参见后面介绍。
  • imagePath :图片上传后保存的路径,如"images/",实现上传到"{{MEDIA_ROOT}}/images"文件夹。 注意:如果imagePath值只设置文件夹,则未尾要有"/" imagePath可以按python字符串格式化:如"images/%(basename)s_%(datetime)s_%(rnd)s.%(extname)s"。这样如果上传test.png,则文件会 被保存为"{{MEDIA_ROOT}}/images/test_20140625122399_259.png"。 imagePath中可以使用的变量有:
  • time :上传时的时间,datetime.datetime.now().strftime("%H%M%S")
  • date :上传时的日期,datetime.datetime.now().strftime("%Y%m%d")
  • datetime :上传时的时间和日期,datetime.datetime.now().strftime("%Y%m%d%H%M%S")
  • year : 年
  • month : 月
  • day : 日
  • rnd : 三位随机数,random.randrange(100,999)
  • basename : 上传的文件名称,不包括扩展名
  • extname : 上传的文件扩展名
  • filename : 上传的文件名全称
  • filePath : 附件上传后保存的路径,设置规则与imagePath一样。
  • upload_settings : 字典值, 例:upload_settings={ imagePathFormat:"images/%(basename)s_%(datetime)s.%(extname)s", imageMaxSize:323232, fileManagerListPath:"files" }
  • upload_settings的内容就是static/ueditor/php/config.json里面的配置内容,因此,你可以去看config.json或者官方文档内容来决定 该如何配置upload_settings,基本上就是用来配置上传的路径、允许上传的文件扩展名、最大上传的文件大小之类的。
  • 上面的imagePath和filePath被单独提取出来配置,原因是因为这两个参数是最常使用到的,imagePath就相当于upload_settings里面的 imagePathFormat,filePath就相当于upload_settings里面的filePathFormat。
  • upload_settings里面设置了imagePathFormat,也可以在UeditorField里面设置imagePath,效果是一样的。但是如果两者均设置, 则imagePath优先级更高。
  • 涂鸦文件、截图、远程抓图、图片库的xxxxPathFormat如果没有配置,默认等于imagePath.
  • 远程文件库的xxxxPathFormat如果没有配置,默认等于filePath.
  • settings : 字典值,配置项与static/ueditor/ueditor.config.js里面的配置项一致。
  • command : 可以为Ueditor新增一个按钮、下拉框、对话框,例:
        Description = UEditorField(u'描述', blank=True, toolbars="full", imagePath="cool/", settings={"a": 1},command=[myBtn(uiName="mybtn1", icon="d.png", title="aaa", ajax_url="/ajaxcmd/"),myCombo(uiName="myCombo3",title="ccc",initValue="111")])
      

command 列表中的按钮是 commands 模块下 UEditorCommand 的实例列表:

​ UEditorButtonCommand:可以在Ueditor上增加一个按钮

​ UEditorComboCommand:可以在Ueditor上增加一个下拉框

​ UEditorDialogCommand:可以在Ueditor上增加一个对话框,暂时未实现

也可以自定义:

        from DjangoUeditor.commands import UEditorButtonCommand,UEditorComboCommand
    #定义自己的按钮命令类
    class myBtn(UEditorButtonCommand):
        def onClick(self):
            return u"""
                alert("爽!");       //这里可以写自己的js代码
                editor.execCommand(uiName);
            """
        def onExecuteAjaxCommand(self,state):
        """  默认在command代码里面加入一段ajax代码,如果指定了ajax_url和重载本方法,则在单点按钮后
         会调用ajax_url.本方法重载是可选的。
         """
            if state=="success":
                return u"""
                    alert("后面比较爽!"+xhr.responseText);//这里可以写ajax成功调用的js代码
                """
            if state=="error":
                return u"""
                    alert("讨厌,摸哪里去了!"+xhr.responseText);//这里可以写ajax错误调用的js代码
                """
      

父类UEditorCommand有4个初始化参数:

​ uiName:按钮名称

​ title:按钮提示信息

​ index:按钮显示的位置索引

​ ajax_url:单击时调用的ajax url

  • event_handler : 用来为Ueditor实例绑定事件侦听,比如以下示例的功能是:当选择区改变时将按钮状态设置为禁止:
        from DjangoUeditor.commands import UEditorEventHandler
    class myEventHander(UEditorEventHandler):
        def on_selectionchange(self):
            return """
              function getButton(btnName){
                  var items=%(editor)s.ui.toolbars[0].items;
                  for(item in items){
                      if(items[item].name==btnName){
                          return items[item];
                      }
                  }
              }
              var btn=getButton("mybtn1");
              var selRanage=id_Description.selection.getRange()
              btn.setDisabled(selRanage.startOffset == selRanage.endOffset);

          """
      

说明:

  • 我们可以继承UEditorEventHandler创建自己的事件侦听类,例如上面myEventHander,然后在myEventHander中 增加on_eventname的方法,在里面返回侦听该event的js代码。例如上例on_selectionchange,就会在前端js中 生成id_Description.addListener('selectionchange', function () {.......});
  • 如果要侦听contentchange事件,就在myEventHander中增加一个on_contentchange方法,然后在该方法中返回js代码。

4.模型应用

​ 富文本库的使用,都是为了提交带格式的内容,因此一般都应用在模型上,我们新建一个模型:

        from DjangoUeditor.models import UEditorField

class Article(models.Model):

    title = models.CharField(max_length=100, verbose_name='标题')

    create_time = models.DateTimeField(auto_now_add=True, verbose_name='发表时间')
    # 富文本字段
    content = UEditorField( width=600, height=300, toolbars="full", imagePath="images/", filePath="files/", upload_settings={"imageMaxSize":1204000},
             settings={}, verbose_name='内容', blank=True, null=True)

    class Meta:

        verbose_name_plural = verbose_name = '文章'
      

说明:

  • 应用 UEditorField 字段类
  • 别忘记去settings修改时区,TIME_ZONE = 'Asia/Shanghai' 否则写入数据库的时间是 UTC 时间
  • imagePath

5.执行数据库迁移

​ 配置好settings中的数据库

        python manage.py makemigrations

python manage.py migrate
      

6.使用admin管理模型

admin.py:

        admin.site.register(Article)
      

7.访问admin后台

需要先创建账号:

        python manage.py createsuperuser
      

8.处理图片文件

  1. settings中:
        MEDIA_URL ='/media/'

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
      
  1. 在根目录下创建 media 文件夹
  2. 根urls:
        from django.conf import settings
from django.conf.urls.static import static

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

9.模板中应用

​ 使用 ModelForm 使用富文本

首先在子应用中新建forms.py,然后在模块中新增:

        class ArticleModelForm(forms.ModelForm):

    class Meta:
        model = Article

        fields = ['title', 'content']
      

说明:

如果不使用ModelForm,那么在一般的Form类中则使用以下两种方式:

  • DjangoUeditor.forms.UEditorField

python class TestUEditorForm(forms.Form): Content=UEditorField("描述",initial="abc",width=600,height=800)

  • DjangoUeditor.widgets.UEditorWidget

```python class TestUEditorForm(forms.Form): Content=forms.CharField(label="内容",widget=UEditorWidget(width=800,height=500, imagePath='aa', filePath='bb',toolbars={}))

```

  1. 显示列表

urls:

path('articles/', views.articles, name='articles'),

templates:新增ueditor_app/articles.html

django <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>文章列表</title> </head> <body> <ul> <li><a href="{% url 'ueditor_app:article' %}">新增文章</a></li> {% for article in articles %} <li>标题:{{ article.title }},创建时间:{{ article.create_time|date:"Y-m-d H:i:s" }}, <a href="{% url 'ueditor_app:article_update' %}?id={{ article.id }}">修改</a></li> {% endfor %} </ul> </body> </html>

views:

python def articles(request): articles = Article.objects.all() return render(request, 'ueditor_app/articles.html', {'articles':articles})

  1. 新增

urls:

python path('article/', views.article, name='article'), path('article_add/', views.article_add, name='article_add'),

templates:新增ueditor_app/article.html

django <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>新增文章</title> {{ form.media }} </head> <body> <form method="post" action="{% url 'ueditor_app:article_add' %}"> {% csrf_token %} <table> {{ form }} <tr> <td colspan="2"> <input type="submit" value="新增"> </td> </tr> </table> </form> </body> </html>

说明:

  • {{ form.media }}:用于导入ueditor必须的js文件
  • {{ form }}:用于显示title和content,其中content是ueditor,会自动编写javascript代码,根据content的id进行初始化

views:

```python def article(request): form = ArticleModelForm() return render(request, 'ueditor_app/article.html', {'form': form})

def article_add(request): form = ArticleModelForm(request.POST)

        if form.is_valid():
       form.save()

   return redirect('ueditor_app:articles')
      

```

  1. 修改

urls:

path('article_update/', views.article_update, name='article_update'),

templates:新增ueditor_app/article_update.html

django <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>修改文章</title> {{ form.media }} </head> <body> <form method="post" action="{% url 'ueditor_app:article_update' %}"> {% csrf_token %} <input type="hidden" name="id" value="{{ form.instance.id }}"> <table> {{ form }} <tr> <td colspan="2"> <input type="submit" value="修改"> </td> </tr> </table> </form> </body> </html>

views:

```python def article_update(request): if request.method == 'POST': id = request.POST.get('id') article = Article.objects.get(pk=id) form = ArticleModelForm(request.POST, instance=article)

        if form.is_valid():
           form.save()

       return redirect('ueditor_app:articles')
   else:
       id = request.GET.get('id')

       article = Article.objects.get(pk=id)

       form = ArticleModelForm(instance=article)

       return render(request, 'ueditor_app/article_update.html', {'form': form})
      

```

10.全局配置

​ 在settings中可以增加全局的配置

        UEDITOR_SETTINGS={ 
    "config":{ 
        # 这里放ueditor.config.js里面的配置项
        # 和UeditorField类中的 settings 一样配置
    }, 
    "upload":{ 
        # 这里放php/config.json里面的配置项,
        # 和UeditorField类中的 upload_settings 一样配置
    } 
}
      

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐