渲染评论楼及内容,渲染评论框,ajax渲染临时评论
HTML
{#评论楼渲染 开始#}
<div>
<ul class="list-group">
{% for comment in comment_list %}
<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>
<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>
{% endif %}
{{ comment.content }}
</div>
</li>
{% endfor %}
</ul>
</div>
{#评论楼渲染 结束#}
{# 评论区分页开始#}
<div class="pull-right">
{{ page_obj.page_html|safe }}
</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 'reg' %}">注册</a></li>
<li><a href="{% url 'login' %}">登录</a></li>
{% endif %}
{# 文章评论结束 #}
发表评论的功能只有登录后才可以使用,判断用户是否登录,如果登录了,就渲染,评论框,没有登录,就渲染登录注册按钮。
知识点:
1 :request.user.is_authenticated 这个功能,在前后端都可以使用。
2:
{% for comment in comment_list %}
{{ forloop.counter }} //用来记录循环到了第几次
{% endfor %}
3 :
时间格式化 {{ comment.comment_time|date:'Y-m-d h:i:s' }}
4:
"{% url 'login' %}" //反向解析
js
//用户点击评论按钮朝后端发送ajax请求
//设置一个全局的parentID字段
let parentId = null;
$('#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 }}',
'content': conTent,
//如果parentId,没有值,那后端存取null没关系
'parent_id': parentId,
'csrfmiddlewaretoken': '{{ csrf_token }}'
},
success: function (args) {
if (args.code == 1000) {
$('#errors').text(args.msg)
//将评论框里面的内容清空
$('#id_comment').val('')
//临时渲染评论楼
var userName = '{{ request.user.username }}';
var temp = `
<li class="list-group-item">
<span>${userName}</span>
<span><a href="#" class="pull-right">回复</a></span>
<div>
${conTent}
</div>
</li>
`
// 将生成好的标签添加到url标签内
$('.list-group').append(temp)
//清空全局的parentId字段
parentId = null;
}
}
})
})
//给回复按钮回复点击事件
$('.reply').click(function () {
// 点回复,就是要回复别人的评论,所以需要别人的姓名和评论的主键值
// 获取用户名
let commentUserName = $(this).attr('username');
// 获取主键值 直接修改全局的主键值
parentId = $(this).attr('comment_id');
// 拼接信息 塞给评论框
$('#id_comment').val('@' + commentUserName + '\n').focus()
})
知识点:
1 :
let indexNum = conTent.indexOf('\n') + 1
conTent.indexOf('\n') // 获取某个字符在字符串中的索引位置
2:
conTent = conTent.slice(indexNum) // 字符串切除,括号里面放的是索引值
3:
$('.list-group').append(temp) //向已有的标签内添加新的html标签。达到改变页面的结果
4:
let commentUserName = $(this).attr('username'); // .attr()获取或设置 HTML 元素的属性。
5:
$('#id_comment').val('@' + commentUserName + '\n').focus()
.val() 获取或设置表单元素的值,如输入框、下拉列表、单选按钮等的值。
.focus() 使特定的表单元素获取焦点(输入框,文本区域等),方便用户直接输入内容
6:
temp:` .... ` // ES6 中的语法, 后面是两个反斜杠 (英文状态下,按esc下面那个按钮)
用于向已有的HTML属性中添加新的 html标签
后端
一个例子,随便看看就行。没啥用
# 获取当前文章所有的评论内容
comment_list = models.Comment.objects.filter(article=article_obj)
def comment(request):
if request.is_ajax():
if request.method == 'POST':
back_dic = {'code': 1000, 'msg': ''}
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_dic['msg'] = '评论成功'
else:
back_dic['code'] = 1001
back_dic['msg'] = '请先登录'
return JsonResponse(back_dic)