我正在制作我的Django评论系统。到目前为止我所做的是:
AJAX初始评论(附加父评论,无页面刷新/保存到数据库)
Django初始评论(能够在页面刷新后呈现上面的父评论)
AJAX第一回复(附加第一个回复,没有页面刷新/保存到数据库)
现在这就是我要做的事情。由于我想拥有一个线程(无尽的)评论系统,用户可以不断地相互回复,我想在开始之前清楚地了解我将如何做到这一点。我的Comment
模型如下所示:
class Comment(models.Model):
user = models.ForeignKey(User, blank=True, null=True)
destination = models.CharField(default='1', max_length=12, blank=True)
parent_id = models.IntegerField(default=0)
comment_text = models.TextField(max_length=350, blank=True, null=True)
def __str__(self):
return self.comment_text
我的AJAX调用如下所示:
var str = window.location.href.split('?')[0];
var path = str.split("/")[4];
$('.comment_form').on('submit', function(e) {
e.preventDefault();
var c = $(this).find('.comment_text').val()
$.ajax({
type: 'POST',
url: '/user_comment/',
data: {
text: $(this).find('.comment_text').val(),
id: path,
csrfmiddlewaretoken: $("input[name='csrfmiddlewaretoken']").val(),
},
success: function(data) {
$('.commentsContainer hr').prepend("<div class='comment_div'><div class='left_comment_div'>" +
<h3><a href='#' class='username'>" + data.username +
"</a></h3><p>" + data.text +
"</p><a href='#'><span class='comment_delete'>x</span></a></div>");
}
});
});
评论模板
<div class="commentsContainer">
<form action="" class="comment_form">{% csrf_token %}
{{ comment.comment_text|add_class:"comment_text" }}
{{ comment.id }}
<input type="submit" value="Comment" class="comment_submit">
</form>
<hr>
{% for i in comment_list %}
<div class='comment_div' data-comment_id="{{ i.id }}">
<div class="left_comment_div">
<div class="username_and_votes">
<h3><a class='username_foreign'>{{ i.user }}</a></h3>
</div>
<br>
<p>{{ i.comment_text }}</p>
</div>
<a class="reply">reply</a><a class="cancel_comment">cancel</a>
<span><a class="comment_delete" data-comment_id="{{ i.id }}">x</a></span>
</div>
{% endfor %}
</div>
这是我的观点:
def user_comment(request):
if request.is_ajax():
comment = CommentForm(request.POST or None)
ajax_comment = request.POST.get('text')
id = request.POST.get('id')
if comment.is_valid():
comment = Comment.objects.create(comment_text=ajax_comment, destination=id, user=request.user)
comment.save()
username = str(request.user)
return JsonResponse({'text': ajax_comment,'username': username, 'id': comment.id})
现在我也开始尝试回复,但我可能没有采用正确的方式,所以请随意忽略以下代码,因为可能有更好的方法。有了回复的jQuery前端,我不得不做一个单独的功能,因为使用相同的功能是行不通的。我还必须制作一个onclick
才能使其正常运行。因此,当用户点击回复按钮时,它会克隆最初的comment_form
并在他们回复的评论后附加:
$('.reply').on('click', function(e) {
var clone = $('.comment_form').clone();
parent_id = $(this).closest('.comment_div').data('comment_id');
$(this).closest('.comment_div').after(
clone
);
clone.addClass('reply_comment_form').removeClass('comment_form');
clone.attr('onclick', 'reply_comment()');
clone.data('comment_id', parent_id);
$(this).next().css('display', 'inline-block');
$(this).css('display', 'none');
});
//然后当他们提交实际回复评论时:
function reply_comment() {
$('.reply_comment_form').on('submit', function (e) {
e.preventDefault();
parent_id = $('.reply_comment_form').data('comment_id');
$.ajax({
type: 'POST',
url: '/comment_reply/',
data: {
reply_text: $(this).find('.comment_text').val(),
parent_id: parent_id,
id: path,
csrfmiddlewaretoken: $("input[name='csrfmiddlewaretoken']").val(),
},
success: function(data) {
$('.reply_comment_form').replaceWith("<div class='comment_div new_comment'><div class='left_comment_div'>" +
"<h3><a href='#' class='username'>" + data.username +
"</a></h3> + data.reply_text +
"</p><a href='#'><span class='comment_delete'>x</span></a></div>");
$('.new_comment').css({
'width': '72%',
'margin': '0 70 10 0',
'float': 'right',
});
$('.new_comment').next().css('clear', 'both');
$('.new_comment').prev().find('.cancel_comment').css('display', 'inline-block')
.find('.cancel_comment').css('display', 'inline-block');
}
});
});
}
回复视图:
def comment_reply(request):
if request.is_ajax():
comment = CommentForm(request.POST or None)
reply_text = request.POST.get('reply_text')
id = request.POST.get('id')
parent_id = request.POST.get('parent_id')
if comment.is_valid():
comment = Comment.objects.create(comment_text=reply_text, destination=id, user=request.user, parent_id=parent_id)
comment.save()
username = str(request.user)
return JsonResponse({'reply_text': reply_text, 'username': username})
我已将第一次回复的parent_id
等同于原始评论的comment.id
。但正如我所说,这样的链接可能不是最好的方式,那么我如何链接评论及其回复呢?我是否在Comment
模型中创建了另一个字段?我可以以某种方式使ForeignKey引用回相同的Comment
模型吗?在呈现回复的回复方面,它如何在模板中起作用,因为它是连续的。
建议很高兴。
答案 0 :(得分:0)
我能以某种方式让一个ForeignKey引用回来 评论模型?
class Comment(models.Model):
parent = models.ForeignKey('self', related_name='children')
text = models.TextField(max_length=350, blank=True)
在渲染方面,它如何在模板中起作用 答复的答复,因为它是连续的
您可以执行以下操作:制作模板comment.html
。
{% for comment in comments %}
<p>{{ comment.text }}</p>
{% if comment.children %}
{% include "comment.html" with comments=comment.children %}
{% endif %}
{% endfor %}
但是你应该在视图中进行预取以减少查询次数。我不确定如何在任何深度上做到这一点。但对于预定义的深度,可以这样做:Comment.objects.prefetch_related('children__children__children')