添加(富文本编辑器)

Posted sima-3

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了添加(富文本编辑器)相关的知识,希望对你有一定的参考价值。

一.文章详情

路由url.py:

    url(r^(?P<username>\w+)/article/(?P<pk>\d+)$, views.article_detail),

点击个人站点文章title即可关联到文章详情路由找到其视图函数

views.py:

def article_detail(request,username,pk):
    user = models.UserInfo.objects.filter(username=username).first()
    if not user:
        return render(request, error.html)
    blog = user.blog
    category_ret=models.Category.objects.all().filter(blog=blog).annotate(cou=Count(article__nid)).values_list(title,cou,nid)
    tag_ret=models.Tag.objects.all().filter(blog=blog).annotate(cou=Count(article__nid)).values_list(title,cou,nid)
    year_ret=models.Article.objects.all().annotate(month=TruncMonth(create_time)).values(month).annotate(c=Count(nid)).values_list(month,c)

    article=models.Article.objects.filter(nid=pk).first()
    # commit_list=article.commit_set.all()   前台模板渲染也可获取评论列表
    return render(request,article_detail.html,locals())

 

ps: 通过有名分组拿到用户名和文章id,找到该文章对象渲染到article_detail.html (用到了母版base.html)

base.html:

 

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title> blog.title 的个人站点</title>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
    <link rel="stylesheet" href="/static/css/ blog.theme ">
    <script src="/static/jquery-3.3.1.js"></script>
    % block mycss %

    % endblock %
</head>
<body>
<div class="head">
     blog.site_name 
</div>
<div class="container-fluid">
    <div class="row">
        <div class="col-md-3">
            <div class="panel panel-danger">
                <div class="panel-heading">我的标签</div>
                <div class="panel-body">
                    % for tag in tag_ret %
                        <p><a href="/ user.username /tag/ tag.2 "> tag.0 ( tag.1 )</a></p>
                    % endfor %

                </div>
            </div>

            <div class="panel panel-success">
                <div class="panel-heading">
                    <h3 class="panel-title">随笔分类</h3>
                </div>
                <div class="panel-body">
                    % for category in category_ret %
                        <p>
                            <a href="/ user.username /category/ category.2 "> category.0 ( category.1 )</a>
                        </p>

                    % endfor %
                </div>
            </div>
            <div class="panel panel-success">
                <div class="panel-heading">
                    <h3 class="panel-title">随笔档案</h3>
                </div>
                <div class="panel-body">
                    % for year in year_ret %
                        <p>
                            <a href="/ user.username /archive/ year.0|date:"Y-m" "> year.0|date:"Y年m月" ( year.1 )</a>
                        </p>
                    % endfor %
                </div>
            </div>
        </div>
        <div class="col-md-9">
            % block content %

            % endblock %
        </div>
    </div>
</div>
</body>
</html>

 

article_detail.html:

% extends base.html %

% block mycss %
    <link rel="stylesheet" href="/static/css/commoncss.css">
% endblock %


% block content %
    <div>
        <h4> article.title </h4>
        <div>
             article.content|safe 
        </div>
        <div class="clearfix">
            <div id="div_digg">
                <div class="diggit upanddown">
                    <span class="diggnum" id="digg_count"> article.up_num </span>
                </div>
                <div class="buryit upanddown">
                    <span class="burynum" id="bury_count"> article.down_num </span>
                </div>
                <div class="clear"></div>
                <div class="diggword" id="digg_tips" style="color: red;"></div>
            </div>
        </div>

        <div>
            #评论相关#
            <div>
                #评论列表#
                <p>评论列表</p>
                <ul class="list-group commit_content">
                    % for commit in article.commit_set.all %
                        <li class="list-group-item">
                            <p>
                                <span># forloop.counter  楼</span>
                                <span> commit.create_time|date:"Y-m-d H:i" </span>
                                <span> commit.user.username </span>
                                <span class="pull-right reply" username=" commit.user.username "
                                      commit_id=" commit.pk "><a>回复</a></span>
                            </p>
                            % if commit.parent %
                                <p class="well">@ commit.parent.user.username ---- commit.parent.content </p>
                            % endif %
                             commit.content 


                        </li>
                    % endfor %
                </ul>

            </div>
            <div>
                #发表评论#
                <p>发表评论</p>
                <p>
                    昵称:<input type="text" id="tbCommentAuthor" class="author" disabled="disabled" size="50"
                              value=" request.user.username ">
                </p>
                <p>评论内容</p>
                <textarea name="" id="id_textarea" cols="80" rows="10">

                </textarea>
                <p>
                    <button class="btn btn-success" id="btn_submit">提交</button>
                </p>
            </div>


        </div>


    </div>
    <script>
        var parent_id = ‘‘
        //评论相关
        $("#btn_submit").click(function () 
            var content = $("#id_textarea").val()

            if (parent_id) 
                //有值,截取前面的@姓名
                //indexof 截取 \n的索引位置
                var index = content.indexOf(\n) + 1
                content = content.slice(index)
            
            //谁对那篇文章评论了什么内容
            $.ajax(
                url: /commit/,
                type: post,
                data: 
                    article_id: article.pk,
                    content: content,
                    csrfmiddlewaretoken:  csrf_token ,
                    parent_id: parent_id
                ,
                success: function (data) 
                    console.log(data)
                    //清除输入框的数据
                    $("#id_textarea").val("")
                    if (data.code == 100) 
                        var username = data.username
                        var reply_content = data.reply_content
                        //往后追加内容
                        if (parent_id) 
                            var parent_name = data.parent_name
                            var s = `
                                <li class="list-group-item">
                                <p>
                                    <span>$username</span>
                                </p>
                                    <p class="well">@$parent_name</p>
                                    $reply_content
                                </li>
                        `
                         else 
                            //追加根评论的内容
                            //es6的字符串替换

                            var s = `
                                <li class="list-group-item">
                                <p>
                                    <span>$username</span>
                                </p>
                                    $reply_content
                                </li>
                        `
                        


                        $(".commit_content").append(s)
                    

                
            )

        )
        //回复相关
        $(".reply").click(function () 
            var username = @ + $(this).attr(username) + \n
            parent_id = $(this).attr(commit_id)
            //光标聚焦到该控件上

            $("#id_textarea").focus()
            $("#id_textarea").val(username)

        )


        //点赞点踩相关
        $(".upanddown").click(function () 
            //当前点击控件有没有diggit 这个类
            var is_up = $(this).hasClass(diggit)
            //拿到当前点击控件子控件的span标签对象
            var cu_span = $(this).children(span)
            //alert(is_up)
            //谁对哪篇文章点赞或点踩
            $.ajax(
                url: /diggit/,
                type: post,
                data: article_id: article.pk, is_up: is_up, csrfmiddlewaretoken:  csrf_token ,
                success: function (data) 
                    console.log(data)
                    $("#digg_tips").html(data.msg)
                    if (data.code == 100) 
                        #cu_span.text(cu_span.text()+1)#
                        //在当前点击的div下的span标签上数字加以
                        cu_span.text(Number(cu_span.text()) + 1)
                    
                
            )

        )
    </script>
% endblock %

文章详情展示了以下内容:  文章title,  文章content (传html文件,用safe转义),点赞点踩,评论列表,评论内容:

a.点赞点踩:

        <div class="clearfix">
            <div id="div_digg">
                <div class="diggit upanddown">
                    <span class="diggnum" id="digg_count"> article.up_num </span>
                </div>
                <div class="buryit upanddown">
                    <span class="burynum" id="bury_count"> article.down_num </span>
                </div>
                <div class="clear"></div>
                <div class="diggword" id="digg_tips" style="color: red;"></div>
            </div>
        </div>

 

js:

 //点赞点踩相关
        $(".upanddown").click(function () 
            //当前点击控件有没有diggit 这个类
            var is_up = $(this).hasClass(diggit)
            //拿到当前点击控件子控件的span标签对象
            var cu_span = $(this).children(span)
            //alert(is_up)
            //谁对哪篇文章点赞或点踩
            $.ajax(
                url: /diggit/,
                type: post,
                data: article_id: article.pk, is_up: is_up, csrfmiddlewaretoken:  csrf_token ,
                success: function (data) 
                    console.log(data)
                    $("#digg_tips").html(data.msg)
                    if (data.code == 100) 
                        #cu_span.text(cu_span.text()+1)#
                        //在当前点击的div下的span标签上数字加以
                        cu_span.text(Number(cu_span.text()) + 1)
                    
                
            )

 点赞点踩视图函数: 开启事务,将点赞点踩表创建记录的同时,把文章表的点赞或点踩数也加一

import json
from django.db.models import F
def diggit(request):
    response=code:100,msg:None
    #当前登陆用户id
    if request.user.is_authenticated():
        user_id=request.user.nid
        is_up=request.POST.get(is_up)
        print(type(is_up))
        print(is_up)
        is_up=json.loads(is_up)
        print(type(is_up))
        print(is_up)
        article_id=request.POST.get(article_id)
        up_ret=models.UpAndDown.objects.filter(user_id=user_id,article_id=article_id).first()
        if up_ret:
            response[code] = 102
            response[msg] = 您已经点过了
        else:
            #事务性的操作
            from django.db import transaction
            #开启事务
            with transaction.atomic():
                models.UpAndDown.objects.create(article_id=article_id,user_id=user_id,is_up=is_up)
                if is_up:
                    #文章表点赞字段加一
                    models.Article.objects.filter(pk=article_id).update(up_num=F(up_num)+1)
                    response[msg] = 点赞成功
                else:
                    models.Article.objects.filter(pk=article_id).update(down_num=F(down_num)+1)
                    response[msg] = 点踩成功

    else:
        response[code]=101
        response[msg]=请先登陆
    return JsonResponse(response,safe=False)

 

 

 

b.评论列表:

        <div>
            #评论相关#
            <div>
                #评论列表#
                <p>评论列表</p>
                <ul class="list-group commit_content">
                    % for commit in article.commit_set.all %
                        <li class="list-group-item">
                            <p>
                                <span># forloop.counter  楼</span>
                                <span> commit.create_time|date:"Y-m-d H:i" </span>
                                <span> commit.user.username </span>
                                <span class="pull-right reply" username=" commit.user.username "
                                      commit_id=" commit.pk "><a>回复</a></span>
                            </p>
                            % if commit.parent %
                                <p class="well">@ commit.parent.user.username ---- commit.parent.content </p>
                            % endif %
                             commit.content 


                        </li>
                    % endfor %
                </ul>

            </div>

c.发表评论:

            <div>
                #发表评论#
                <p>发表评论</p>
                <p>
                    昵称:<input type="text" id="tbCommentAuthor" class="author" disabled="disabled" size="50"
                              value=" request.user.username ">
                </p>
                <p>评论内容</p>
                <textarea name="" id="id_textarea" cols="80" rows="10">

                </textarea>
                <p>
                    <button class="btn btn-success" id="btn_submit">提交</button>
                </p>
            </div>

js:

        var parent_id = ‘‘
        //评论相关
        $("#btn_submit").click(function () 
            var content = $("#id_textarea").val()

            if (parent_id) 
                //有值,截取前面的@姓名
                //indexof 截取 \n的索引位置
                var index = content.indexOf(\n) + 1
                content = content.slice(index)
            
            //谁对那篇文章评论了什么内容
            $.ajax(
                url: /commit/,
                type: post,
                data: 
                    article_id: article.pk,
                    content: content,
                    csrfmiddlewaretoken:  csrf_token ,
                    parent_id: parent_id
                ,
                success: function (data) 
                    console.log(data)
                    //清除输入框的数据
                    $("#id_textarea").val("")
                    if (data.code == 100) 
                        var username = data.username
                        var reply_content = data.reply_content
                        //往后追加内容
                        if (parent_id) 
                            var parent_name = data.parent_name
                            var s = `
                                <li class="list-group-item">
                                <p>
                                    <span>$username</span>
                                </p>
                                    <p class="well">@$parent_name</p>
                                    $reply_content
                                </li>
                        `
                         else 
                            //追加根评论的内容
                            //es6的字符串替换

                            var s = `
                                <li class="list-group-item">
                                <p>
                                    <span>$username</span>
                                </p>
                                    $reply_content
                                </li>
                        `
                        


                        $(".commit_content").append(s)
                    

                
            )

        )
        //回复相关
        $(".reply").click(function () 
            var username = @ + $(this).attr(username) + \n
            parent_id = $(this).attr(commit_id)
            //光标聚焦到该控件上

            $("#id_textarea").focus()
            $("#id_textarea").val(username)

        )

评论视图函数:开启事务,在评论表添加记录的同时,也在文章表添加评论数

def commit(request):
    response = code: 100, msg: None
    # 当前登陆用户id
    if request.user.is_authenticated():
        user_id = request.user.nid
        article_id = request.POST.get(article_id)
        content=request.POST.get(content)
        parent_id=request.POST.get(parent_id)
        # 事务性的操作
        from django.db import transaction
        # 开启事务
        with transaction.atomic():
            ret=models.Commit.objects.create(article_id=article_id,content=content,user_id=user_id,parent_id=parent_id)
            models.Article.objects.filter(pk=article_id).update(comment_num=F(comment_num) + 1)
            response[username]=ret.user.username
            response[reply_content]=ret.content
            if parent_id:
                response[parent_name] = ret.parent.user.username
            response[msg] = 评论成功



    else:
        response[code] = 101
        response[msg] = 请先登陆
    return JsonResponse(response, safe=False)

二.后台展示,添加文章

路由url.py:

    # 后台管理首页
    url(r^backend/, views.home_backend),

视图函数:

from django.contrib.auth.decorators import login_required
@login_required(login_url=/login/)
def home_backend(request):
    #查询该人的所有文章
    ariticle_list=models.Article.objects.filter(blog=request.user.blog)
    return render(request,backend/home_backend.html,locals())

前端渲染母版backend_base.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>后台管理</title>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
    <script src="/static/jquery-3.3.1.js"></script>
    <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.js"></script>
</head>
<body>
<div class="head" style="height: 60px;background-color: #2b669a">
    <p>后台管理</p>
</div>
<div class="container-fluid">
    <div class="row">
        <div class="col-md-3">
            <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
                <div class="panel panel-default">
                    <div class="panel-heading" role="tab" id="headingOne">
                        <h4 class="panel-title">
                            <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseOne"
                               aria-expanded="true" aria-controls="collapseOne">
                                文章管理
                            </a>
                        </h4>
                    </div>
                    <div id="collapseOne" class="panel-collapse collapse in" role="tabpanel"
                         aria-labelledby="headingOne">
                        <div class="panel-body">
                            <a href="/add_article/">添加文章</a>
跳到添加文章路由
</div> </div> <div id="xxx" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingOne"> <div class="panel-body"> <a href="">添加随笔</a> </div> </div> </div> </div> </div> <div class="col-md-9"> <div> <!-- Nav tabs --> <ul class="nav nav-tabs" role="tablist"> <li role="presentation" class="active"><a href="#home" aria-controls="home" role="tab" data-toggle="tab">文章</a></li> <li role="presentation"><a href="#profile" aria-controls="profile" role="tab" data-toggle="tab">随笔</a> </li> <li role="presentation"><a href="#messages" aria-controls="messages" role="tab" data-toggle="tab">交友</a> </li> <li role="presentation"><a href="#settings" aria-controls="settings" role="tab" data-toggle="tab">相册</a> </li> </ul> <!-- Tab panes --> <div class="tab-content"> <div role="tabpanel" class="tab-pane active" id="home"> % block content % % endblock % </div> <div role="tabpanel" class="tab-pane" id="profile">随笔</div> <div role="tabpanel" class="tab-pane" id="messages">交友</div> <div role="tabpanel" class="tab-pane" id="settings">相册</div> </div> </div> </div> </div> </div> </body> </html>

后台管理前端home_backend.html:

% extends backend/backend_base.html %

% block content %
    <table class="table table-striped">
        <thead>
        <tr>
            <th>标题</th>
            <th>评论数</th>
            <th>点赞数</th>
            <th>操作</th>
            <th>操作</th>
        </tr>
        </thead>
        <tbody>
        % for ariticle in ariticle_list %
            <tr>
                <td><a href="/ request.user.username /article/ ariticle.pk "> ariticle.title </a></td>
跳到文章详情路由 <td> ariticle.commit_num </td> <td> ariticle.up_num </td> <td><a href="">删除</a></td> <td><a href="">编辑</a></td> </tr> % endfor % </tbody> </table> % endblock %

 

 添加文章路由:

    # 添加文章
    url(r^add_article/, views.add_article),

添加文章视图函数:(用bs4来解析html文档,删除script标签内容来防止xss

@login_required(login_url=/login/)
def add_article(request):
    if request.method==GET:
        return render(request,backend/add_article.html)
    else:
        title=request.POST.get(title)
        text_content=request.POST.get(text_content)
        #通过bs4 处理xss攻击,html文档解析库
        #pip3 install beautifulsoup4
        from bs4 import BeautifulSoup
        soup=BeautifulSoup(text_content,html.parser)
        #查找所有的标签
        tags=soup.find_all()
        for tag in tags:
            if tag.name==script:
                #从文档中删除该标签
                tag.decompose()
        #soup.text 文档的内容,不包含标签
        desc=soup.text[0:150]
        models.Article.objects.create(title=title,desc=desc,content=str(soup),blog=request.user.blog)
        return redirect(/backend/)

 

 添加文章add_article.html(借助富文本编辑器):

% extends backend/backend_base.html %

% block content %

    <div>
        <p>添加文章</p>
        <form action="/add_article/" method="post">
            % csrf_token %
            <div class="form-group">
                <label for="id_name">文章标题</label>
                <input type="text" name="title" id="id_title" class="form-control">
            </div>
            <p>内容(KindEditor编辑器,不支持拖放/粘贴上传图片) </p>
            <textarea name="text_content" id="editor_id" cols="30" rows="10"></textarea>
            <p>
                <button class="btn btn-success">提交</button>
            </p>
        </form>

    </div>
    <script charset="utf-8" src="/static/kindeditor/kindeditor-all.js"></script>

    <script>

        KindEditor.ready(function (K) 
            window.editor = K.create(#editor_id, 
                width: 100%,
                height: 400px,
                resizeType: 0,
                #items: [#
                #    ‘source‘, ‘|‘, ‘undo‘, ‘redo‘, ‘|‘, ‘preview‘, ‘print‘, ‘template‘, ‘code‘, ‘cut‘, ‘copy‘, ‘paste‘,#
                #    ‘plainpaste‘, ‘wordpaste‘, ‘|‘#
                #]#
                uploadJson: /uploadimg/,
                extraFileUploadParams: 
                    csrfmiddlewaretoken:  csrf_token ,
                

            );
        );
    </script>
% endblock %

在富文本编辑器中上传图片,图片地址放在media/file下即可:

@login_required(login_url=/login/)
def uploadimg(request):
    response=
        "error" : 0,
        "url" : None
    
    fil=request.FILES.get(imgFile)
    with open(media/file/+fil.name,wb) as f:
        for line in fil:
            f.write(line)
        response[url]=/media/file/+fil.name
    return JsonResponse(response)

 

以上是关于添加(富文本编辑器)的主要内容,如果未能解决你的问题,请参考以下文章

django中集成富文本编辑器

Ueditor百度富文本编辑器添加h5手机端预览功能

给vue添加一个超级好用的富文本编辑器 markdown

富文本编辑器-1-选型

搭建自己的博客(十三):为博客后台添加ckeditor富文本编辑器

完成后台管理系统功能KindEditor富文本编辑器的使用以及商品添加的实现