【问题标题】:Advice on making a threaded comment system in Django在 Django 中制作线程评论系统的建议
【发布时间】:2017-02-01 22:23:14
【问题描述】:

我正在制作我的 Django 评论系统。到目前为止我所做的是:

  • AJAX 初始 cmets(父注释附加而不刷新页面/保存到数据库)

  • Django初始cmets(页面刷新后可以渲染上面的父cmets)

  • 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>");
        }

});

});

cmets 模板

<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 模型吗?以及它如何在模板中工作,就呈现回复的回复而言,因为它是连续的。 建议表示赞赏。

【问题讨论】:

    标签: jquery ajax django django-models


    【解决方案1】:

    我能否以某种方式制作一个 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')

    【讨论】:

      猜你喜欢
      • 2014-09-11
      • 2011-07-16
      • 2018-05-24
      • 1970-01-01
      • 2011-10-24
      • 2012-07-08
      • 2019-02-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多