1 后台管理

1.1 页面设计

创建路由映射

# 后台管理url
re_path("cn_backend/$",views.cn_backend),
re_path("cn_backend/add_article/$",views.add_article),

创建后台管理首页的视图函数

@login_required
def cn_backend(request):
    """
    后台管理的首页
    :param request:
    :return:
    """
    article_list = models.Article.objects.filter(user=request.user)

    return render(request, "backend/backend.html", locals())

创建后台管理页面

# base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>博客后台管理 - 博客园</title>

    <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css">
    <script src="/static/js/jquery-3.2.1.min.js"></script>
    <script src="/static/blog/bs/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="/static/blog/css/backend.css">
</head>
<body>

<div class="header">
    <p class="title">
        后台管理

        <a class="info" href="/logout/">注销</a>
        <span class="info"><span class="glyphicon glyphicon-user"></span>&nbsp;&nbsp;{{ request.user.username }}</span>
    </p>
</div>


<div class="container">
    <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">
                        <p><a href="/cn_backend/add_article/">添加文章</a></p>
                    </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">

                    <img src="/static/blog/img/meinv2.jpg" alt="">
                    <img src="/static/blog/img/meinv3.jpg" alt="">
                    <img class="pull-right" src="/static/blog/img/meinv.jpg" alt="">
                </div>
                <div role="tabpanel" class="tab-pane" id="messages">

                    <img width="180" height="180" src="/static/blog/img/hashiqi2.jpg" alt="">

                    <img width="180" height="180" src="/static/blog/img/dogg4.jpg" alt="">
                    <img width="180" height="180" src="/static/blog/img/linhaifeng.jpg" alt=""><br>
                    <img width="180" height="180" src="/static/blog/img/dogg3.jpeg" alt="">
                    <img width="180" height="180" src="/static/blog/img/dogge2.jpg" alt="">

                    <img width="180" height="180" src="/static/blog/img/dogg5.jpg" alt="">

                </div>
                <div role="tabpanel" class="tab-pane" id="settings">

                </div>
            </div>

        </div>

    </div>
</div>

</body>
</html>
{% extends 'backend/base.html' %}


{% block content %}
 <div class="article_list small">

     <table class="table table-hover table-striped">
         <thead>
             <th>标题</th>
             <th>评论数</th>
             <th>点赞数</th>
             <th>操作</th>
             <th>操作</th>
         </thead>
         <tbody>
             {% for article in article_list %}
             <tr>
                 <td>{{ article.title }}</td>
                 <td>{{ article.comment_count }}</td>
                 <td>{{ article.up_count }}</td>
                 <td><a href="">编辑</a></td>
                 <td><a href="">删除</a></td>
             </tr>
             {% endfor %}

         </tbody>
     </table>
</div>
{% endblock %}

创建添加文章页面

{% extends 'backend/base.html' %}

{% block content %}
<form action="" method="post">
    {% csrf_token %}
   <div class="add_article">
     <div class="alert-success text-center">添加文章</div>

     <div class="add_article_region">
          <div class="title form-group">
             <label for="">标题</label>
             <div>
                 <input type="text" name="title">
             </div>
         </div>

         <div class="content form-group">
             <label for="">内容(Kindeditor编辑器,不支持拖放/粘贴上传图片) </label>
             <div>
                 <textarea name="content" id="article_content" cols="30" rows="10"></textarea>
             </div>
         </div>

         <input type="submit" class="btn btn-default">

     </div>
</div>
</form>   

{% endblock %}

1.2 富文本编辑器

KindEditor 是一套开源的在线HTML编辑器,主要用于让用户在网站上获得所见即所得编辑效果,开发人员可以用 KindEditor 把传统的多行文本输入框(textarea)替换为可视化的富文本输入框。 KindEditor 使用 JavaScript 编写,可以无缝地与 Java、.NET、PHP、ASP 等程序集成,比较适合在 CMS、商城、论坛、博客、Wiki、电子邮件等互联网应用上使用。

为了能够更好地在后台编辑文章,我们在项目中引入富文本编辑器中的其中一款kindeditor

<script src="/static/js/jquery-3.2.1.min.js"></script>
<script charset="utf-8" src="/static/blog/kindeditor/kindeditor-all.js"></script>

<script>
    KindEditor.ready(function(K) {
            window.editor = K.create('#article_content',{
                width:"800",
                height:"600",
                resizeType:0,
                uploadJson:"/upload/",
                extraFileUploadParams:{
                    csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val()
                },
                filePostName:"upload_img"


            });
    });
</script>

后端对应设置:

路由:

# 文本编辑器上传图片url
path('upload/', views.upload),

视图:

def upload(request):
    """
    编辑器上传文件接受视图函数
    :param request:
    :return:
    """

    print(request.FILES)
    img_obj=request.FILES.get("upload_img")
    print(img_obj.name)

    path=os.path.join(settings.MEDIA_ROOT,"add_article_img",img_obj.name)

    with open(path,"wb") as f:

        for line in img_obj:
            f.write(line)


    return HttpResponse("ok")

1.3 添加文章的逻辑实现

from bs4 import BeautifulSoup


@login_required
def add_article(request):
    """
    后台管理的添加书籍视图函数
    :param request:
    :return:
    """
    if request.method == "POST":
        title = request.POST.get("title")
        content = request.POST.get("content")

        # 防止xss攻击,过滤script标签
        soup=BeautifulSoup(content,"html.parser")
        for tag in soup.find_all():

            print(tag.name)
            if tag.name=="script":
                tag.decompose()

        # 构建摘要数据,获取标签字符串的文本前150个符号

        desc=soup.text[0:150]+"..."

        models.Article.objects.create(title=title,desc=desc,content=str(soup), user=request.user)
        return redirect("/cn_backend/")

    return render(request, "backend/add_article.html")

OVER!

results matching ""

    No results matching ""