项目分析
如果想评论一个文章,要拿到什么数据:
1.文章id
2.用户id
3.评论内容
4.父评论id(子评论)
1.文章的id通过个人主页的a标签拿到<a href="{{ foo.user.username }}/article/{{ foo.pk }}">{{ foo.title }}</a>
,url为url(r"^(\w+)/(\w+)/article/(\d+)/$", views.article_detail),
,最后把pk传递给显示文章详情的视图def article_detail(request, username, username1, pk):
2.用户通过user = models.UserInfo.objects.filter(username=username).first()
拿到
3.评论内容通过前端发送ajax传递
4.父评论id,通过pid = $(this).attr("comment_pk");
,在点击的回复按钮中定义一个属性拿到.
前端
技术点:
前端截取字符串的操作和each遍历列表
标签内设置属性以及拿到标签内属性
{% extends 'base.html' %}
{% block page-main %}
<div class="article-detail">
<h1>{{ article.title }}</h1>
<p>{{ article.articledetail.content | safe }}</p>
</div>
<div>
<div style="margin-top: 50px;margin-left: 500px; " class="action">
<span class="glyphicon glyphicon-thumbs-up action1" id="digg_count">{{ article.up_count }}</span>
<span class="glyphicon glyphicon-thumbs-down less action1"
id="bury_count">{{ article.down_count }}</span>
</div>
</div>
<div id="error" style="color: red;"></div>
<p>评论树</p>
<div class="comment_tree">
</div>
<hr>
<p>评论列表</p>
<ul class="comment_list">
{% for comment in comment_list %}
<li class="list-group-item">
<div>
<a href="">#{{ forloop.counter }}楼</a>
<span style="color: gray;">{{ comment.create_time|date:"Y-m-d" }}</span>
<span>{{ comment.user.username }}</span>
<a class="pull-right reply_btn" username="{{ comment.user.username }}"
comment_pk="{{ comment.pk }}"><span>回复</span></a>
</div>
{% if comment.parent_comment_id %}
<div class="pid_info">
<p>{{ comment.parent_comment.user.username }} {{ comment.parent_comment.content }}</p>
</div>
{% endif %}
<div class="con">
<p>
{{ comment.content }}
</p>
</div>
</li>
{% endfor %}
</ul>
<div class="div_comment">
<p>
昵称<input type="text" id="tbCommentAuthor" disabled="disabled" class="author" size="50"
value="{{ request.user.username }}">
</p>
<p>
评论:
</p>
<textarea name="" id="comment_content" cols="50" rows="10"></textarea>
<button id="comment_btn">提交评论</button>
</div>
<div class="clear"></div>
<div class="info" style="display: none;" username="{{ request.user.username }}" article_id="{{ article.pk }}"></div>
{#点赞,反对#}
<script>
$(".action .action1").click(function () {
if ($(".info").attr("username")) {
{% comment %}如果当前点击的块中有...up这个类就是true{% endcomment %}
var is_up = $(this).hasClass("glyphicon-thumbs-up");
var article_id = "{{ article.pk }}";
$.ajax({
url: "/blog/up_down/",
type: "get",
data: {
"is_up": is_up,
"article_id": article_id,
{#"csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val()#}
},
success: function (data) {
if (data.status) {
if (is_up) {
var v = $("#digg_count").text();
v = parseInt(v) + 1;
$("#digg_count").text(v);
}
else {
var v = $("#bury_count").text();
v = parseInt(v) + 1;
$("#bury_count").text(v);
}
}
else {
if ($(".action").click()) {
$("#error").html("您已经推荐过");
setTimeout(function () {
$("#error").html("");
}, 1000)
}
else if ($(".action1").click()) {
$("#error").html("您已经反对过");
setTimeout(function () {
$("#error").html("");
}, 1000)
}
}
}
})
}
else {
location.href = "/login/"
}
})
</script>
{# 根评论and子评论#}
<script>
//获取评论数据,展示评论树
$.ajax({
url: "blog/comment_tree/" + '{{ article.pk }}/',
type: "get",
success: function (data) {
console.log(data);
$.each(data, function (index, comment_dict) {
var s = '<div style="margin-left:20px" comment_id="' + comment_dict.pk + '">\n' + '<span class="content">' + comment_dict.content + '</span>\n' + '</div>'
if (comment_dict.parent_comment_id) {
//子评论
pid = comment_dict.parent_comment_id;
$("[comment_id=" + pid + "]").append(s)
} else {//根评论
$(".comment_tree").append(s)
}
})
}
});
//提交评论
var pid = "";
$("#comment_btn").click(function () {
var article_id = $(".info").attr("article_id");
var content = $("#comment_content").val();
if (pid) {
//子评论把用户名截掉
var index = content.indexOf("\n");
content = content.slice(index + 1);
}
$.ajax({
url: "/blog/comment/",
type: "get",
data: {
article_id: article_id,
content: content,
pid: pid,
},
success: function (data) {
console.log(data);
var comment_li = '<li class="list-group-item"> <div> <span style="color: gray;">' + data.create_time + '</span> <span>' + data.username + '</span> <a href="" class="pull-right"><span>回复</span></a> </div> <div class="con"> <p> ' + data.content + ' </p> </div> </li>';
//标签
$(".comment_list").append(comment_li);
if (pid) {
var comment_li = '<div class="pid_info">\n' + '<p>' + data.comment_parent_username + ' ' + data.comment_parent_content + '</p>\n' + '</div>';
$(".comment_list").append(comment_li);
}
//清空输入框
$("#comment_content").val("");
//清空pid
pid = "";
}
})
});
{# 回复按钮 #}
$(".list-group-item .reply_btn").click(function () {
$("#comment_content").focus();
var v = "@" + $(this).attr("username");
$("#comment_content").val(v + ":\n");
pid = $(this).attr("comment_pk");
})
</script>
{% endblock %}
后端
1.article_detail:通过文章id拿到文章对象,通过用户名拿到用户对象,通过用户对象拿到博客对象,通过文章id拿到所有的评论.
2.Comment:通过ajax传过来的父评论id,文章id和内容,保存到数据库,并且返回给前端
3.comment_tree:评论树
def article_detail(request, username, username1, pk):
# pk是文章主键
article_obj = models.Article.objects.filter(pk=pk).first()
print(article_obj)
user = models.UserInfo.objects.filter(username=username).first()
if not user:
return HttpResponse("404")
blog = user.blog
# 找到所有的评论
comment_list = models.Comment.objects.filter(article_id=pk)
return render(request, "article_detail.html", {"article": article_obj, "blog": blog,"comment_list":comment_list})
def comment(request):
print(request.GET)
pid = request.GET.get("pid")
article_id = request.GET.get("article_id")
content = request.GET.get("content")
user_pk = request.user.pk
response = {}
if not pid:# 根评论
comment_obj = models.Comment.objects.create(article_id=article_id,user_id=user_pk,content=content)
else:
comment_obj=models.Comment.objects.create(article_id=article_id,user_id=user_pk,content=content,parent_comment_id=pid)
response["comment_parent_username"] = comment_obj.parent_comment.user.username
response["comment_parent_content"] = comment_obj.parent_comment.content
response["create_time"] = comment_obj.create_time
response["content"] = comment_obj.content
response["username"] = comment_obj.user.username
return JsonResponse(response)
def comment_tree(request,article_id):
print(5555)
ret = list(models.Comment.objects.filter(article_id=article_id).values("pk","content","parent_comment_id"))
print(ret)
# 如果JsonResponse返回的参数不是字典,就需要加上safe参数,设置成False
return JsonResponse(ret,safe=False)