2017-02-01 5 views
0

Я нахожусь в середине создания моей системы комментариев Django. Что я сделал до сих пор:Советы по созданию многопоточной системы комментариев в Django

  • AJAX начальных комментарии (родительское добавление комментария без обновления страницы/сохраняется в базу данных)

  • Джанго первоначальные комментарии (возможность оказывать родительские комментарии выше после обновления страницы)

  • AJAX первый ответ (первый ответ добавляется без обновления страницы/сохраняется в базе данных)

Сейчас это где я U p to. Поскольку я хочу иметь поточную (бесконечную) систему комментариев, в которой пользователи могут непрерывно отвечать друг другу, я хочу иметь четкое представление о том, как я это сделаю, прежде чем я начну. Моя 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 из 1 отвечает равным comment.id оригинального комментария. Но, как я сказал, связывание таких, как это, вероятно, не самый лучший способ, так как я могу связать комментарий и его ответы? Создать другое поле в модели Comment? Могу ли я каким-то образом заставить ForeignKey ссылаться на ту же модель Comment? И как он работает в шаблоне с точки зрения предоставления ответов на ответы, поскольку он является непрерывным. Совет с пониманием.

ответ

0

Мог ли я каким-то образом заставить ForeignKey ссылаться на то же самое? Комментировать модель?

class Comment(models.Model): 
    parent = models.ForeignKey('self', related_name='children') 
    text = models.TextField(max_length=350, blank=True) 

И как это работает в шаблоне, с точки зрения оказания ответы ответов, becauses это непрерывный

Вы можете сделать что-то вроде этого: сделать шаблон 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')