|
前期思路# 文章评论
我们先写跟评论
再写子评论
前端HTML代码{#评论楼开始#}
<div>
<ul class="list-group">
{% for comment in comment_list %} # 文章的视图函数把comment_list对象传过来,comment_list = models.Comment.objects.filter(article=article_obj)
<li class="list-group-item">
<span>#{{ forloop.counter }}楼</span>
<span>{{ comment.comment_time|date:'Y-m-d h:i:s' }}</span>
<span>{{ comment.user.username }}</span> <!--.user跨到userinfo表,.username在继承的abstract里面找到username属性-->
<span><a class="pull-right reply" username="{{ comment.user.username }}" comment_id="{{ comment.pk }}">回复</a></span>
<div>
{# 判断当前评论是否是子评论 如果是则需要渲染对应的评论人名#}
{% if comment.parent_id %}
<p>@{{ comment.parent.user.username }}</p> <!--子评论如何拿到根评论的名字,还是跨表通过parent就可以了-->
{% endif %}
{{ comment.content }}
</div>
</li>
{% endfor %}
</ul>
</div>
{#评论楼结束#}{#文章样式评论开始#}
{% if request.user.is_authenticated %} # 判断登录的用户才能评论
<div>
<p><span class="glyphicon glyphicon-comment"></span>发表评论</p>
<div>
<textarea name="comment" id="id_comment" cols="60" rows="10"></textarea>
</div>
<button class="btn btn-primary" id="id_submit">提交评论</button>
<span style="color: red" id="errors"></span>
</div>
{% else %} # 非登录用户跳转登录、注册页面
<li><a href="{% url 'login' %}">登录</a></li>
<li><a href="{% url 'reg' %}">注册</a></li>
{% endif %}{#文章样式评论结束#}
前端JS代码// 设置一个全局标志位置,为了让子评论的值可以传递到后端
let parentId =null
// 用户点击评论朝后端发送ajax请求
$('#id_submit').click(function (){
// 获取用户评论的内容
let conTent=$('#id_comment').val()
// 判断是否是子评论,如果是则需要手动将@username名字去除掉
if(parentId){
// 先找到\n对应的索引 然后利用切片 但是切片是顾头不顾尾 搜易索引索引+1
let indexNum = conTent.indexOf('\n') +1 ;
conTent=conTent.slice(indexNum) // 将indexNum所有的数据切除,只保留后面的部分
}
$.ajax({
url: '/comment/',
type: 'post',
data:{
'article_id': '{{ article_obj.pk }}',
// 如果后端没有值 那么就是null 后端存储null没有任何关系
'parent_id':parentId,
'content':conTent,
'csrfmiddlewaretoken':'{{csrf_token}}'
},
success:function (args){
if(args.code==1000){
$('#errors').text(args.msg)
//利用ajax success回调结果俩实现两个功能
// 1、将评论区内容清空
// 2、搭建一个临时的评论楼到评论去底部
// 1、将评论区里面的内容清空
$('#id_comment').val('')
// 2、临时渲染评论楼
let userName = '{{ request.user.username }}'
let temp = `
<li class="list-group-item">
<span>${userName}</span>
<span><a href="#" class="pull-right">回复</a></span>
<div>
${conTent}
</div>
</li> `
// 将生成好的标签加到到评论楼里面去,append尾部追加一个临时的评论楼
$('.list-group').append(temp);
// 要清空全局的parentId字段
parentId =null
}
}
})
})
// 用户进行子评论
$('.reply').click(function (){
// 用户名字和评论id
let commentUserName =$(this).attr('username')
// 修改全局的parent_id ,如果全部变量为可变类型的时候不用加global申明和python一样的用法
parentId =$(this).attr('comment_id')
// 跳转到textarea中,把@+作者名字+换行添加进去
$('#id_comment').val('@'+commentUserName+'\n').focus()
})
后端代码:from django.db import transaction # 利用事务同时提交两个models语句
def comment(request):
# 自己也可以给自己的文章经行评论
if request.is_ajax():
back_dic = {'code': 1000, 'msg': ''}
if request.method == 'POST':
# 后端也可以再次校验是否登录
if request.user.is_authenticated():
article_id = request.POST.get('article_id')
content = request.POST.get('content')
parentId = request.POST.get('parent_id') # 如果是根评论这个值是可以为空的
# 要操作两张表一个是文章表com_num 另外一个COMMENT表
with transaction.atomic():
models.Article.objects.filter(pk=article_id).update(comment_num=F('comment_num')+1)
models.Comment.objects.create(user=request.user,content=content,article_id=article_id,parent_id=parentId)
back_dic['msg']='评论成功'
else:
back_dic['code']=1001
back_dic['msg']='用户未登录'
return JsonResponse(back_dic) # 只接收post请求,get请求就不返回了
|
|
|