• BBS项目之文章评论


    BBS项目之文章评论

    需求分析

    #  需求1
    不许匿名用户评论,提供登录/注册的接口
    #  需求2
    可以评论别人的文章,也可以回复别人对自己文章的评论(即根评论与子评论)
    #  需求3
    评论的渲染方式有两种,点击评论按钮,使用DOM操作临时渲染评论楼;刷新URL,使用render渲染评论楼
    #  需求4
    给回复按钮绑定两个属性,当前根评论的用户,以及评论的主键值
    

    数据库表设计

    class Comment(models.Model):
        """评论表"""
        user = models.ForeignKey(to='UserInfo')
        article = models.ForeignKey(to='Article')
        content = models.CharField(verbose_name='评论内容', max_length=255)
        comment_time = models.DateTimeField(verbose_name='评论时间', auto_now_add=True)
        # 自关联
        parent = models.ForeignKey(to='self', null=True)  # 有些评论就是根评论
    

    这里需要注意的是:

    我们知道根评论与子评论的区别在于,子评论多了一个parent_id,因此评论表中的自关联字段parent必须设置null=True,否则,所有的评论都是子评论,没有根评论。

    代码

    前端

    {% if request.user.is_authenticated %}
                <div>
                    <a href="#" style="text-decoration: none" title="发表评论"><img src="/static/img/comment.png" alt=""
                                                                                style=" 20px;height: 20px">&nbsp;&nbsp;发表评论</a>
                    <div>
                        <div>
                            <span style="color: red" id="thanks"></span>
                        </div>
                        <textarea name="comment" id="id_comment" cols="60" rows="10" placeholder="支持Markdown"></textarea>
                    </div>
                    <button class="btn btn-primary" id="id_submit">提交评论</button>
                    <span style="color: red" id="error"></span>
                </div>
            {% else %}
                <div>
                    <a href="{% url 'login' %}" style="text-decoration: none">登录</a>&nbsp;&nbsp;
                    <a href="#" class="register_model" style="text-decoration: none">注册</a>
                </div>
            {% endif %}
            
            
            //设置一个全局的parentId
            let parentId = null;
            //用户点击评论按钮后直接朝后端发送ajax请求
            $('#id_submit').on('click', function () {
                let content = $('#id_comment').val();
                //判断当前的评论是否为子评论,如果是去除 /n之前的字符
                if (parentId) {
                    //利用切片操作(找到
    的索引,然后利用切片,切片顾头不顾尾)
                    let indexNum = content.indexOf('
    ') + 1;
                    content = content.slice(indexNum); //将indexNum之前的所有数据切除,只保留后面的一部分
                }
                $.ajax({
                    url: '/comment/',
                    type: 'post',
                    data: {
                        'article_id': '{{ article_obj.pk }}',
                        'content': content,
                        'parent_id': parentId, //如果没有点击回复parentId就是Null
                        'csrfmiddlewaretoken': '{{ csrf_token }}',
                    },
                    success: function (args) {
                        if (args.code === 1600) {
                            //将评论框的内容清空
                            $('#id_comment').val('');
                            //感谢回复
                            $('#thanks').html('感谢您的回复☺:');
                            //临时渲染评论楼
                            let username = '{{ request.user.username }}';
                            let temp = `
                                <a href='#' style="text-decoration: none;" title='发表评论'><img src="/static/img/comment.png" alt="" style=" 20px;height: 20px">&nbsp;&nbsp;${username}</a>
                                <div class="panel panel-info">
                                    <div class="panel-body">
                                        ${content}
                                    </div>
                                </div>`;
                            $('.content-group').append(temp);
                            //清空全局的parentId字段
                            parentId = null;
                        }
                    }
                })
            });
    
    
    

    后端

    def comment(request):
        # 自己也可以给自己评论
        if request.is_ajax():
            back_dict = {'code': 1600, 'msg': ''}
            if request.method == 'POST':
                if request.user.is_authenticated:
                    article_id = request.POST.get('article_id')
                    content = request.POST.get('content')
                    # 获取父评论
                    parent_id = request.POST.get('parent_id')
                    # 直接操作评论表 存储数据  两张表
                    # 开事务
                    with transaction.atomic():
                        models.Article.objects.filter(pk=article_id).update(comment_num=F('comment_num') + 1)
                        models.Comment.objects.create(user=request.user, article_id=article_id, content=content,
                                                      parent_id=parent_id)
                    back_dict['msg'] = '评论成功'
                else:
                    back_dict['code'] = 1601
                    back_dict['msg'] = '用户未登录'
                return JsonResponse(back_dict)
    
    
  • 相关阅读:
    电路原理图分析
    GPIO学习——用户空间操作
    在Android上运行Java和C程序
    Android命令行工具学习总结
    Android蓝牙学习笔记
    33 把数组排成最小的数
    233 Number of Digit One
    32 从1到n整数中1出现的次数
    31 连续子数组的最大和
    《大型网站技术架构》学习笔记
  • 原文地址:https://www.cnblogs.com/surpass123/p/13150018.html
Copyright © 2020-2023  润新知