BBS(仿博客园系统)项目05(后台管理功能实现:文章添加、富文本编辑器使用、xss攻击、BeautifulSoup4模块、富文本编辑器上传图片、修改头像)

摘要

  • 布局框架搭建
  • 随笔添加
  • 后台管理富文本编辑器KindEditor
  • xss攻击
  • 文章简介的截取,BeautifulSoup4模块
  • 富文本编辑器上传图片
  • 头像修改

一、后台管理框架布局搭建

后台管理布局框架分析:导航条、左侧功能区、右侧主要功能显示和实现区

实现:

导航条:使用bootstrap模板:JavaScript>>导航条

左侧:使用bootstrap模板:组件>>列表组

右侧:使用bootstrap模板:JavaScript>>标签页

新建后台管理路由(注意放在站点路由上面)

url(r‘^backend/‘, views.backend),

views.py视图函数:

@login_required
def backend(request):
    user_obj = request.user
    article_list = models.Article.objects.filter(blog=user_obj.blog)
    return render(request, ‘backend/backend.html‘, locals())

渲染后台管理页面(单独在templates文件夹下创建后台管理文件夹backend,然后在此文件夹下新建backend.html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>后台管理</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
    <style>
        #top_left {
            font-weight: bold;
            font-size: 24px;
            color: black;
        }

        #top_title {
            color: blue;
            font-size: 18px;
            font-weight: bold;
            font-family: "微软雅黑 Light";
        }
    </style>
    {% block css %}

    {% endblock %}
</head>
<body>
{#后台管理导航条#}
<nav class="navbar navbar-default">
    <div class="container-fluid">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                    data-target="#bs-example-navbar-collapse-5" aria-expanded="false">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="/home/" id="top_left">博客园后台管理</a>
            <p class="navbar-text" id="top_title">{{ request.user.blog.blog_title }}</p>
        </div>
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-5">
            <p class="navbar-text navbar-right">
                <a href="/{{ request.user.username }}/" class="navbar-link">{{ request.user.username }}</a>
            </p>
        </div>
    </div>
</nav>
{#            <a class="navbar-brand" href="#" id="top_left">博客园后台管理</a>#}
{##}
{#                <li><a id="top_title" href="">{{ request.user.blog.blog_title }}</a></li>#}
{#                <li><a id="top_right" href="#">{{ request.user.username }}</a></li>#}

<div class="container-fluid">
    <div class="row">
        {# 后台管理左侧快捷入口占用2个栅格#}
        {#    左侧信息展示:需要参数:tag_list category_list date_list user_obj#}
        <div class="col-md-2 col-sm-2 col-xs-3">
            <div class="list-group">
                <li class="list-group-item list-group-item-info">操作</li>
                <a href="/add_article/" class="list-group-item">添加新随笔</a>
                <a href="#" class="list-group-item">草稿箱</a>
                <a href="#" class="list-group-item">添加新文章</a>
                <a href="#" class="list-group-item">其它...</a>
            </div>
            <hr>
            <div class="list-group">
                <li class="list-group-item list-group-item-warning">分类</li>
                <a href="#" class="list-group-item">编辑分类</a>
                <a href="#" class="list-group-item">所有分类</a>
                <a href="#" class="list-group-item">其它...</a>
            </div>
        </div>
        {# 后台管理右侧管理主要内容展示区占用10个栅格#}
        {#      右侧文章列表需要参数:article_list#}
        <div class="col-md-10 col-sm-10 col-xs-9">
            {% block content %}
                <div>
                    <!-- Nav tabs -->
                    <ul class="nav nav-tabs" role="tablist">
                        <li role="presentation" class="active"><a href="#article" 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="article">
                                <table class="table table-hover table-striped">
                                    <thead>
                                        <tr>
                                            <th>标题</th>
                                            <th class="text-center">发布时间</th>
                                            <th class="text-center">评论数</th>
                                            <th class="text-center">点赞数</th>
                                            <th>操作</th>
                                            <th>操作</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        {% for article in article_list %}
                                            <tr>
                                                <td><a href="/{{ article.blog.userinfo.username }}/article/{{ article.pk }}/">{{ article.title }}</a></td>
                                                <td class="text-center">{{ article.create_time|date:‘Y-m-d‘ }}</td>
                                                <td class="text-center">{{ article.comment_num }}</td>
                                                <td class="text-center">{{ article.up_num }}</td>
                                                <td><a href="">编辑</a></td>
                                                <td><a href="">删除</a></td>
                                            </tr>
                                        {% endfor %}
                                    </tbody>
                                </table>
                        </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>
            {% endblock %}
        </div>
    </div>
</div>
{% block js %}

{% endblock %}
</body>
</html>

大致效果:

二、添加新随笔

先来一顿操作:

建路由:

url(r‘^add_article/‘, views.add_article),

渲染页面:继承后台管理主页面

{% extends ‘backend/backend.html‘ %}
{% block css %}
    <style>
        #title {
            margin-top: 5px;
            background-color: rgba(35,206,235,0.2);
            height: 22px;
            border-top: 1px gray solid;
            border-bottom: 1px gray dashed;
        }
    </style>

{% endblock %}
{% block content %}
<div>
<p id="title">添加随笔</p>
<p>标题
    <input type="text" class="form-control">
</p>
</div>

视图函数:

def add_article(request):
    return render(request, ‘backend/add_article.html‘)

然后就可以在上面的基础上继续进行:

富文本编辑器KindEditor的使用

下载该插件后,解压,将其文件夹复制到static文件夹下

使用KindEditor需要借助textarea输入框,所以需要在添加随笔处添加一个textarea框

BeautifulSoup4模块

①表单在提交后,后端需要对文章进行截取一部分作为文章的摘要desc,如果直接对提交的内容content进行切片的话得不到文章的文字内容,因为我们通过富文本编辑器提交的内容实际上都是一行行html代码,同时如果这段代码中存在js脚本的话,有可能会存在xss脚本攻击,这里就需要对随笔内容进行过滤

②先参考一下博客园处理xss攻击的方式:

在HTML源码编辑器中写入<script>alert(123)</script>,更新后再打开

可以看出博客园的内部将此段代码给加了代码,让js脚本没法生效,同时将随笔保存再看发现这段代码被认为删除了。

所以:

博客园处理xss攻击方法:将敏感标签自动添加内容,让其失效,在后端处理时直接过滤掉敏感标签,将其删除。

引入一个模块BeautifulSoup4:可以过滤js脚本和拿到content内的文本内容,再进行切分。

先安装模块
pip3 install beautifulsoup4

# 这里强调一点:一定要下官方推荐的beautifulsoup4版本,因为beautifulsoup3版本已经停止开发

富文本编辑器上传图片

通过富文本编辑器上传图片需要再开一个路由进行处理上传的图片

url(r‘^upload_img/‘, views.upload_img),

视图函数upload_img:

def upload_img(request):
    if request.method == ‘POST‘:
        # 前端富文本编辑器上传的图片key值叫imgFile,拿到文件对象
        img_obj = request.FILES.get(‘imgFile‘)
        print(img_obj.name,type(img_obj.name))
        # 手动拼接文件存放路径,该文件应该存入media文件夹
        path = os.path.join(settings.BASE_DIR, ‘media‘, ‘article_img‘)
        # 判断当前路径是否存在,如果不不存在,则创建文件夹
        if not os.path.exists(path):
            os.mkdir(path)
        # 可以通过img_obj.name,拿到这个文件对象的文件名,然后在拼接文件的路径,用于保存写入
        file_path = os.path.join(path, img_obj.name)
        with open(file_path, ‘wb‘) as f:
            for line in img_obj:
                f.write(line)
        # 这里需要注意富文本编辑器上传图片接收的响应数据格式规定是以下这种形式:
        """
            //成功时
            {
                    "error" : 0,
                    "url" : "http://www.example.com/path/to/file.ext"
            }
            //失败时
            {
                    "error" : 1,
                    "message" : "错误信息"
            }
        """
        back_dic = {
            ‘error‘: 0,
            # 这个url就是前端可以通过路由直接访问到的文件路径,这样做的目的是编辑上传一个图片,编辑器肯定需要
            # 拿到该图片渲染到页面上。
            ‘url‘: ‘/media/article_img/%s‘ % img_obj.name
        }
        return JsonResponse(back_dic)

三、修改头像:

原文地址:https://www.cnblogs.com/suguangti/p/11079961.html

时间: 2024-10-09 09:48:49

BBS(仿博客园系统)项目05(后台管理功能实现:文章添加、富文本编辑器使用、xss攻击、BeautifulSoup4模块、富文本编辑器上传图片、修改头像)的相关文章

python3进阶开发-第一个仿博客园的项目(1)

首先我们要设计一下表结构: UserInfo(用户信息表) -------->一对一    ----------->Blog(博客信息表) UserInfo(用户信息表) --------->一对多    ----------->Article UpDown(点赞表) UserInfo(用户信息表) --------->一对多    ----------->Article Comment(评论表) UserInfo(用户信息表)---------->一对多   

仿博客园编辑器的插入代码 代码高亮功能

代码下载地址:http://download.csdn.net/detail/dfg727/7616305 1. a.配置tinymce,增加一个insert code按钮    b.处理显示页面中展开收缩的高亮部分事件 var tinymce_config = function (selector) { tinymce.init({ selector: selector, theme: "modern", menubar: false, plugins: [ "previe

模拟博客园系统

1. 启动程序, 显?菜单列表      菜单:      1. 登录      2. 注册      3. ?章      4. ?记      5. 退出 2. ?户输入选项, ?章和?记必须在登录后才可以进?操作.(装饰器) 3. ?户注册, 将?户名和密码写入到register?件中. 同时?成"article_?户名"?件?于 存储?户?章. 同时?成"diary_?户名" 来存储?户的?记内容. 4. ?户登录成功后, ?户名和密码从register?件

python简单模拟博客园系统

# 用代码模拟博客园系统## 项目分析:# 1.首先程序启动,显示下面内容供用户选择:## 1.请登录# 2.请注册# 3.进入文章页面# 4.进入评论页面# 5.进入日记页面# 6.进入收藏页面# 7.注销账号# 8.退出整个程序# 2.必须实现的功能:## 1.注册功能要求:# a.用户名.密码要记录在文件中.# b.用户名要求:不能有特殊字符并且确保用户名唯一.# c.密码要求:长度要在6~14个字符之间.## 2.登录功能要求:# a.用户输入用户名.密码进行登录验证.# b.登录成功之

.net模拟登录博客园,使用httpWebRequest登录并发布随笔文章

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.IO; using System.Runtime.InteropServices; using System.Diagnostics; namespace TestHttpWebRequest { class Program { [DllImport("winine

bbs仿博客

BBS表设计 项目开发的流程 需求分析 架构师+产品经理+开发组组长 在去客户公司谈需求之前,先事先估摸着这个项目应该怎么做 里面有哪些坑的点 提前想好比较简单的解决方案 在跟客户谈的时候 有意识的引导客户朝着你已经想好的方案上去提需求 项目设计 架构师干的活 项目的报价(每个程序员按照人头 每天2000+左右) 语言的选择 框架的选择 数据库的选择(主库用什么 缓存库) 功能划分 开发部开发组长开会分发任务 分组开发 架构师和开发组长将项目整体的框架搭建出来 然后让小组成员各自朝着各个部分填写

致博客园团队?关于自己写了个文章还被移除首页!

我遇到了个访问hsql数据库文件的问题,由于自己之前没有用过花了2天时间才大概搞清楚怎么用. 昨天晚上10点多我开始写这个文章,写了个一个多小时才敲完.早上一起来被移除首页! 如下是收到的邮件信息: 博客园团队2018-09-23 08:22 删除 您好,您的博文“访问Hsql .data数据库文件”被移出首页,由此给您带来麻烦,请谅解! 首页是分享知识的地方,我们对发布在首页的博文的基本要求是:原创精品,排版整齐,有足够的篇幅,与程序员相关,能够让读者从中学到知识. 如果工作人员处理不当,请您

BBS仿博客系统 登录功能

先看登录功能的需求: 三个输入框,分别是用户名,密码,验证码,输入错误能够直接把错误显示出来且不刷新整个页面,验证码输入框旁边是一个显示验证码的图片,如果看不清,可以点一下就更换图片,登录成功后跳转到主页 先将页面大致搭建出来 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> &

[cnblogs] 仿博客园插入代码的Windows Live Writer插件

一  插件相关效果图展示 插件效果图: 在Windows Live Writer中的效果如图: [1] [2] [3] 对应的插入代码在博客中的效果如下: [1] public static void Main(string[] args) { int sum = 0; for(int i = 0 ; i < 100 ; i++) { sum += i; } } [2] public static void Main(string[] args) { int sum = 0; for(int i