仿bbs项目之评论功能完善,后台管理功能部分讲解,bs4模块简介

仿bbs项目之评论功能完善,后台管理功能部分讲解,bs4模块简介

昨日内容回顾

  • 个人站点侧边栏筛选功能

    1.研究侧边栏路由规律
    2.初步指定三个路由
    	站点名称\category\分类主键值
        站点名称\tag\标签主键值
        站点名称\archive\年-月
    3.路由优化设计
    	正则匹配
    4.由于筛选还是基于个人站点 所以多个路由使用相同的视图函数
    	通过视图函数接收的实参个数不同从而区分不同的业务逻辑
    5.根据条件二次过滤文章数据
    	正反向查询、神奇的双下划线查询
    
  • 侧边栏inclusion_tag制作

    1.侧边栏很多页面都需要使用 并且还需要传参才可以加载出来
    2.干脆制作成inclusion_tag调用 从而节省代码
    3.自定义操作固定步骤(模板层相关知识)
    
  • 点赞点踩样式搭建

    直接拷贝博客园相关html和css即可
    ps:图片防盗链技术
    
  • 点赞点踩功能完善

    1.前端页面给点赞点踩图标绑定点击事件
    	通过标签class值的不同区分是赞还是踩
        发送ajax请求携带文章主键值、点赞点踩。。。
    2.后端业务逻辑
    	校验用户是否登录、校验当前用户是否是文章作者、校验当前用户是否已经点过、完成数据库操作(注意普通字段(优化的评论数点赞点踩字段)数据更新)
        ps:注意前端发送过来的js类型的布尔值需要自己处理成python布尔值
    3.前端展示优化
    	信息提示、数字动态变化
        ps:针对标签文本需要做类型转换 否则默认是字符串拼接
    
  • 文章评论样式搭建

    最简易的几个标签
    	获取用户输入的textarea以及一个提交按钮
    
  • 文章根评论业务逻辑

    1.给提交按钮绑定点击事件
    2.发送ajax请求
    	携带评论内容、文章主键
    3.后端直接获取数据并写入数据库
    	还是得注意文章表中的普通字段
    ps:很多业务逻辑可能需要执行多条ORM语句 这个时候稳了保证数据的完整可以采用事务操作(回想ORM事务的三种操作方式(全局事务、装饰器,with局部))
    

今日内容概要

  • 根评论完善
  • 子评论回复按钮功能
  • 子评论功能完善
  • 后台管理搭建
  • 添加文章页面搭建
  • 富文本编辑器
  • 添加文章初步实现
  • bs4模块简介

今日内容详细

根评论完善

提交评论
	评论框里面的内容会清空 然后页面会有一个临时评论样式出现 页面刷新才会出现评论样式
    
先提前获取数据,方便使用
            // 获取用户评论的内容
            let commentMsg = $('#comment').val();
            // 提前获取当前用户名字
            let currentUserName = '{{ request.user.username }}'
            
当数据通过一系列校验并返回到ajax内时,清空评论框内容,查找ul标签并添加子标签(临时添加到评论楼,不影响刷新页面的展示)
'''
                success: function (args) {
                    if(args.code === 10000){
                        // 清空评论框内容
                        $('#comment').val('');
                        // 动态创建标签并添加到评论楼中(临时评论楼)
                        let tempComment = `
                        <li class="list-group-item">
                            <span class="glyphicon glyphicon-comment"><a href="/${currentUserName}/">${currentUserName}</a></span>
                            <p>
                                ${commentMsg}
                            </p>
                        </li>
                        `
                        // 查找ul标签动态添加子标签即可
                        $('.list-group').append(tempComment)

                    }
                }
'''

研究子评论特性
	每个评论右侧都应该有回复按钮 点击就可以填写子评论
    点击回复按钮具体动作:评论框中自动添加@+评论人名并换行 聚焦
    	如何区分不同的回复按钮对应的用户名
        	利用标签可以自定义属性直接携带对应的评论用户名即可
            <p class="pull-right"><a href="#" class="reply" username="{{ comment_obj.user.username }}">回复&nbsp;&nbsp;</a></p>
            username:当前评论用户名
            
        '''
        //给回复按钮绑定点击事件
        $('.reply').click(function () {
            let targetUserName = $(this).attr('username');
            $('#comment').val('@' + targetUserName + '\n').focus()
        })
        '''

点击回复按钮发送子评论 页面不刷新的情况下 后续的评论全部成了子评论
	原因是全局变量parentId没有清空导致的 每次提交评论都应该清空一下
'''
// 清空全局变量parentId使下一个评论不再绑定parentId
parentId = null;
'''

针对子评论内的@用户名换行 理论上不属于用户评论的内容 不应该记录到数据库
	前端可以剔除 也可以在后端剔除
'''
前端:
// 如果发送的是子评论,则进行切割处理掉前缀内容
            if(parentId){
                commentMsg = commentMsg.slice(commentMsg.indexOf('\n') + 1)
            }

后端:
判断parentId是否有值,有值则用split切割掉\n之后的内容即可
'''
    
针对子评论的渲染 应该动态判断是否是子评论 如果是应该加上评论的目标用户名
'''
在回复的后面添加p标签
<p>
                    {% if comment_obj.parent_id %}
                        @{{ comment_obj.parent.user.username }}

                    {% endif %}
                </p>
'''

'''
因为临时渲染的评论之前被切割用于后端的使用,再用变量名接收一下没切割之前的评论,用作临时渲染评论
// 获取没处理之前的子评论
            old_commentMsg = commentMsg;
'''

ps:针对评论的渲染也可以分页 也可以做根评论与子评论的集合操作(分类)(楼中楼)

后台管理

1.模仿博客园后台访问直接展示所有文章
2.后台管理页面需要多次被当作模板页面使用 如果该页面也是继承其他页面那么无法二次被继承使用 所以我们单独编写一个后台管理的模板页面、
'''
继承home页面
1.路由
    # 后台管理接口
    path('backend/', views.backend_func),
2.视图
@login_required
def backend_func(request):
    site_obj = models.Site.objects.filter(site_name=request.user.username).first()
    # 获取当前站点下所有的文章
    article_queryset = models.Article.objects.filter(site=site_obj)

    '''文章过多的情况下应该考虑添加分页器'''
    page_obj = myPage.Pagination(current_page=request.GET.get('page'), all_count=article_queryset.count())
    page_queryset = article_queryset[page_obj.start:page_obj.end]
    return render(request, 'backend/backend.html', locals())
    
3.前端直接找样式,然后写table表单和分页器
                    <table class="table table-hover table-striped">
                        <thead>
                            <tr>
                                <th>标题</th>
                                <th>时间</th>
                                <th>评论数</th>
                                <th>点赞数</th>
                                <th>点踩数</th>
                                <th>操作</th>
                                <th>操作</th>
                            </tr>
                        </thead>

                        <tbody>
                        {% for article_obj in page_queryset %}
                            <tr>
                                <td><a href="/{{ site_obj.site_name }}/article/{{ article_obj.pk }}">{{ article_obj.title }}</a></td>
                                <td>{{ article_obj.create_time|date:'Y-m-d H:i:s' }}</td>
                                <td>{{ article_obj.comment_num }}</td>
                                <td>{{ article_obj.up_num }}</td>
                                <td>{{ article_obj.down_num }}</td>
                                <td><a href="#">编辑</a></td>
                                <td><a href="#">删除</a></td>
                            </tr>
                        {% endfor %}
                        </tbody>
                    </table>
                    {{ page_obj.page_html|safe }}
'''

添加文章

1.页面简易搭建
'''
1.路由
    # 后台管理之添加文章接口
    path('add_article/', views.add_article_func),
2.视图
@login_required
def add_article_func(request):
    # 当前站点样式需要当前站点的对象
    site_obj = models.Site.objects.filter(site_name=request.user.username).first()
    category_list = models.Category.objects.filter(site=site_obj)
    tag_list = models.Tag.objects.filter(site=site_obj)

    return render(request, 'backend/addArticlePage.html', locals())
3.前端
    <h2 class="text-center">添加文章</h2>
    <form action="" method="post">
        {% csrf_token %}
        <p>文章标题</p>
        <input type="text" name="title" class="form-control">
        <p>文章内容</p>
        <textarea name="content" id="" cols="30" rows="10" class="form-control"></textarea>
        <p>文章分类</p>
        <p>
            {% for category_obj in category_list %}
                <input type="radio" name="category" value="{{ category_obj.pk }}">{{ category_obj.name }}
            {% endfor %}
        </p>
        <p>文章标签</p>
        <p>
            {% for tag_obj in tag_list %}
                <input type="checkbox" name="tag" value="{{ tag_obj.pk }}">{{ tag_obj.name }}
            {% endfor %}
        </p>
        <input type="submit" class="form-control btn btn-block btn-success">
    </form>
'''

2.文章内容区富文本编辑器的使用
	1.先下载kindeditor富文本编辑器,添加到static静态文件中
    2.js区根据id值导入样式即可
'''
    <script charset="utf-8" src="/static/kindeditor/kindeditor-all-min.js"></script>
    <script charset="utf-8" src="/static/kindeditor/lang/zh-CN.js"></script>
    <script>
        KindEditor.ready(function (K) {
            window.editor = K.create('#mycontent',
                {
                    width : '100%',
                    height : '300px',
                }
            );

        });
    </script>
'''
3.添加文章具体业务代码
'''
    # 根据post请求获取用户输入数据
    if request.method == 'POST':
        title = request.POST.get('title')
        content = request.POST.get('content')
        category_id = request.POST.get('category')
        tag_list = request.POST.get('tag')

        # 操作文章表写入数据
        article_obj = models.Article.objects.create(
            title=title,
            desc=content[1:150],
            content=content,
            site=site_obj,
            category_id=category_id,
        )
        # 因为文章标签与文章多对多 第三张表 自己去操作第三张表
        for tag_id in tag_list:
            models.Article2Tag.objects.create(article=article_obj, tag_id=tag_id)
        return redirect('/backend/')
'''

3.添加文章需要注意的问题
	文章简介不应该有标签存在
	文章内容不允许编辑script脚本(XSS攻击)
    
涉及到html相关内容的处理 可以借助于爬虫相关模块
	bs4

posted @ 2023-01-05 22:11  lsumin  阅读(70)  评论(0编辑  收藏  举报