在comment/models.py中的类Comment中增加新的内容:树结构
# comment/models.py
root = models.ForeignKey('self', related_name='root_comment', null=True, on_delete=models.DO_NOTHING) # 设计底层结构需要用
parent = models.ForeignKey('self', related_name='parent_comment', null=True, on_delete=models.DO_NOTHING) # 外键指向自己
reply_to = models.ForeignKey(User, related_name="replies", null=True, on_delete=models.DO_NOTHING) # 回复谁
def __str__(self): # 为的是显示评论内容的具体内容而不是object
return self.text
迁移
新增一条博客,评论数为0
给comment/admin中的amin.py增加主键值
list_display = ('id', 'content_object', 'text', 'comment_time', 'user')
# id就是主键
修改blog/views.py中的blog_detail方法中的comment
comments = Comment.objects.filter(content_type=blog_content_type, object_id=blog.pk, parent=None) # 多了parent=None 增加初始化值
blog_detail.html中的暂无评论上面添加:
回复
{% for reply in comment.root_comment.all %}
{{ reply.user.username }}
({{ reply.comment_time|date:"Y-m-d H:i:s" }})
回复
{{ reply.reply_to.username }}:
{{ reply.text|safe }}
回复
{% endfor %}
回到admin中对评论设置回复
对comment和reply增加样式:
blog.css:
div.comment {
border-bottom: 1px dashed #ccc;
margin-bottom: 0.5em;
padding-bottom: 0.5em;
}
div.reply {
margin-left: 2em;
}
在到comment/forms.py中增加reply_comment_id字段:
reply_comment_id = forms.IntegerField(widget=forms.HiddenInput(attrs={'id': 'reply_comment_id'}))
效果如下:
在log_detail.html提交按钮中增加function:
function reply(reply_comment_id){
// 设置值
$('#reply_comment_id').val(reply_comment_id);
var html = $("#comment_" + reply_comment_id).html();
$('#reply_content').html(html);
$('#reply_content_container').show();
$('html').animate({scrollTop: $('#comment_form').offset().top - 60}, 300, function(){
CKEDITOR.instances['id_text'].focus();
});
}
然后在欢迎评论下面添加内容:
在comment/forms.py中增加clean_reply_comment_id方法用于对回复内容进行验证;
from .models import Comment
..
def clean_reply_comment_id(self):
reply_comment_id = self.cleaned_data['reply_comment_id']
if reply_comment_id < 0:
raise forms.ValidationError('回复出错')
elif reply_comment_id == 0:
self.cleaned_data['parent'] = None
elif Comment.objects.filter(pk=reply_comment_id).exists():
self.cleaned_data['parent'] = Comment.objects.get(pk=reply_comment_id)
else:
raise forms.ValidationError('回复出错')
return reply_comment_id
然后再coment/views.py中增加判断
parent = comment_form.cleaned_data['parent']
if not parent is None:
comment.root = parent.root if not parent.root is None else parent
comment.parent = parent
comment.reply_to = parent.user
comment.save()
...
data['text'] = comment.text
if not parent is None:
data['reply_to'] = comment.reply_to.username
else:
data['reply_to'] = ''
data['pk'] = comment.pk
data['root_pk'] = comment.root.pk if not comment.root is None else ''
效果图:
修改blog/views.py中的内容,使的评论能够保持正序排列,回复能够倒序
context['comments'] = comments.order_by('-comment_time')