zoukankan      html  css  js  c++  java
  • 博客园-后台管理(富文本编辑器和BS模块)

     

    后台管理页面

    在个人主站 页面中我们设计有管理按钮,当我们点击管理按钮时,应该能进入后台管理自己的文章(注意:这里进入的应该是当前登录人的后台,而不是该站点的后台)

    首先设计url

    复制代码
    from blog import views
    
    
    urlpatterns = [
        # 文章详细页的点赞url
        url(r'digg/$', views.digg),
        # 评论
        url(r'comment/$', views.comment),
        # 后台管理
        url(r'^(?P<username>w+)/backend/$', views.backend),
        
        url(r'^(?P<username>w+)/backend_add_article/$', views.backend_add_article),
    
        # 个人站点的url
        url(r'^(?P<username>w+)/$', views.home_site),
        url(r'^(?P<username>w+)/(?P<condition>cate|tag|date)/(?P<params>.+)/$', views.home_site),
        url(r'^(?P<username>w+)/articles/(?P<article_id>d+).html/$', views.article_detail),
    ]
    复制代码

    视图函数

    def backend(request, username):
        article_list = models.Article.objects.filter(user__username=username)
    
        return render(request, "blog/backend_index.html", locals())

    前端页面

    复制代码
    {% load static %}
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="x-ua-compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="{% static 'bootstrap-3.3.7/css/bootstrap.min.css' %}">
        <link rel="stylesheet" href="{% static 'css/backend_index.css' %}">
        <script src="{% static 'jquery-3.2.1.min.js' %}"></script>
        <script src="{% static 'bootstrap-3.3.7/js/bootstrap.min.js' %}"></script>
        <title>后台管理</title>
    </head>
    <body>
    
    <div class="header">
        <div class="title">{{ username }}</div>
    </div>
    
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-3">
                <ul class="list-group">
                    <li class="list-group-item"><a href="/blog/{{ request.user.username }}/backend_add_article">添加文章</a></li>
                    <li class="list-group-item">分类管理</li>
                    <li class="list-group-item">标签操作</li>
                </ul>
            </div>
            <div class="col-md-9">
                <div class="con">
                    <table class="table table-stripped table-hover">
                        <thead>
                            <tr>
                                <th>文章标题</th>
                                <th>操作</th>
                                <th>操作</th>
                            </tr>
                        </thead>
                        <tbody>
                        {% for article in article_list %}
                            <tr>
                            <td>{{ article.title }}</td>
                            <td><a href="">编辑</a></td>
                            <td><a href="">删除</a></td>
                            </tr>
                        {% endfor %}
    
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
    
    </body>
    </html>
    复制代码

    css式样

    复制代码
    *{
        margin: 0;
        padding: 0;
    }
    .header{
        height: 55px;
         100%;
        background-color: #5e5e5e;
        line-height: 55px;
    }
    .header .title{
        font-size: 24px;
        font-weight: 200;
        color: white;
        margin-left: 20px;
    }
    复制代码

    富文本编辑器

    点击添加文章后我们跳转到一个新的页面进行文章编辑,参照博客园,我们可以看到编辑时有很多功能,这里我们使用富文本编辑器(kindeditor)

    先下载编辑器,再将文件夹放到static目录中引用

    具体可参看官网http://kindeditor.net/demo.php

    前端页面

    复制代码
    {% load static %}
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="x-ua-compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="{% static 'bootstrap-3.3.7/css/bootstrap.min.css' %}">
        <link rel="stylesheet" href="{% static 'css/backend_index.css' %}">
        <script src="{% static 'jquery-3.2.1.min.js' %}"></script>
        <script src="{% static 'bootstrap-3.3.7/js/bootstrap.min.js' %}"></script>
        <title>后台管理</title>
    </head>
    <body>
    
    <div class="header">
        <div class="title">{{ username }}</div>
    </div>
    
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-3">
                <ul class="list-group">
                    <li class="list-group-item"><a href="/blog/{{ request.user.username }}/backend_add_article">添加文章</a></li>
                    <li class="list-group-item">分类管理</li>
                    <li class="list-group-item">标签操作</li>
                </ul>
            </div>
            <div class="col-md-9">
                <form action="" method="post">
                    <div class="title">
                        <label for="">标题:</label>
                        <p><input type="text" name="title"></p>
                    </div>
                    <div class="con">
                        <label for="article_area">内容:(Kindeditor编辑器,支持拖放/粘贴上传图片)</label>
                        <p><textarea name="content" id="article_area" cols="60" rows="10"></textarea></p>
                    </div>
                    <p><input type="submit" value="提交" class="btn btn-default"></p>
                    {% csrf_token %}
                </form>
            </div>
        </div>
    </div>
    
    <script charset="utf-8" src="/static/kindeditor/kindeditor-all.js"></script>
    <script>
            KindEditor.ready(function(K) {
                    window.editor = K.create('#article_area',{
                        '600px',
                        height:'600px',
                        items:[
             'preview', 'print', 'template', 'code', 'cut', 'copy', 'paste',
             'justifycenter', 'justifyright',
             'outdent', 'subscript',
            'superscript', 'clearhtml', 'quickformat', 'selectall', '|', 'fullscreen', '/',
            'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold',
            'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', '|', 'image', 'multiimage',
            'flash', 'media', 'insertfile', 'table', 'hr', 'emoticons', 'baidumap', 'pagebreak',
            'anchor', 'link', 'unlink', '|', 'about'
    ],
                        resizeType:0,
                        uploadJson:"/upload_file/",
                        extraFileUploadParams:{"csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val()},
                        filePostName:"upload_img"
    
                    });
            });
    </script>
    
    </body>
    </html>
    复制代码

    这里可以看到富文本编辑器是配合textarea标签使用的,编辑器使用时有很多参数可以设计(具体见官网)

    这里我们需要注意的是uploadJson参数,这是向服务器传图片等文件时需要设置的,一旦点击了添加图片的功能,就会向该选项后的url发送请求,该请求是post请求

    由于发送post请求需要csrf_token的数据,这里我们使用extraFileUploadParams参数,该参数可以让我们在发送请求时附带一些参数,发送到后端后,后端通过request.FILES可以取到发送的图片,这个值是一个键值对

    此时使用filePostName参数可以设置键为什么,而值则为对应的图片对象

    后端接收图片的视图函数

    复制代码
    def upload_file(request):
        # 保存上传图片到指定路径
        obj = request.FILES.get("upload_img")
        from BlogYuan import settings
        import os
        path = os.path.join(settings.MEDIA_ROOT, "article_img", obj.name)
        with open(path, "wb") as f_write:
            for chunk in obj.chunks():
                f_write.write(chunk)
    
        # 给文本编辑器返回json字符串
        upload_response = {
            "error": 0,  # 0表示没错
            "url": "/media/article_img/%s" % (obj.name)
        }
        return HttpResponse(json.dumps(upload_response))
    复制代码

    接收到图片并保存在服务端的media目录中后,我们需要向前端进行响应,这里需要注意,响应的json字符串中,error字段表示是否有错误,0表示没有错误

    url字段表示图片的路径,只有将他发给前端,前端页面才能预览到图片

    过滤文章内容

    当我们提交了我们的文章后,后台接收到文章内容后,不能直接存到数据库,需要对文章内容进行过滤,去掉一些非法内容

    这里我们使用到了BS(BeautifulSoup)模块,可以对文章中的标签等内容进行搜索、查询、修改等

    BS模块具体使用http://www.cnblogs.com/yuanchenqi/articles/7617280.html

    官方文档http://beautifulsoup.readthedocs.io/zh_CN/latest/

    视图函数

    复制代码
    def backend_add_article(request, username):
        if request.method == "POST":
            content = request.POST.get("content")
            title = request.POST.get("title")
            # 用BS模块过滤content
            valid_tags_attrs_list = {
                "div": ["id", "class", "style"],
                "img": ["src", "width", "height"],
                "a": ["href"],
                "p": []
            }
            from bs4 import BeautifulSoup
            soup = BeautifulSoup(content, "html.parser")
            tags_list = soup.find_all()
            for tag in tags_list:
                if tag.name not in valid_tags_attrs_list:
                    tag.decompose()
                else:
                    for attr in tag.attrs:
                        if attr not in valid_tags_attrs_list[tag.name]:
                            del tag[attr]
        return render(request, "blog/backend_add_article.html")
    复制代码

    这里我们接收到文章的标题和内容,然后自己定义了一个有效的标签字典,里面含有有效的标签属性

    然后通过BS模块拿到文章内容的所有标签,对这些标签进行筛选,删掉无效的标签和无效的标签属性

    成功后可以将数据存入数据库,再跳转到成功页面(上面的代码中未写)

  • 相关阅读:
    区块链 超级节点什么鬼?
    堆排序--模版类
    梯度下降算法Python简单试验
    svn: Can't convert string from 'UTF-8' to native encoding
    常用加密算法比较
    快速排序结合插入排序
    无法解析的外部符号
    mysql 远程连接出错问题
    50个C/C++经典面试题
    设计算法找出字符串中重复出现最长的子串
  • 原文地址:https://www.cnblogs.com/QQ279366/p/8488527.html
Copyright © 2011-2022 走看看