Какой лучший способ разрешить бесконечное количество внешних ключей для одной и той же модели? - PullRequest
0 голосов
/ 10 мая 2011

Я сейчас создаю форум с django и хочу, чтобы каждый мог прокомментировать комментарий другого человека.Прямо сейчас у меня есть внешний ключ в моей модели «Комментарий», который указывает на себя, так что я могу легко получить родительский комментарий из любого комментария.

В моей теории это работало замечательно, потому что из любого комментария я мог получитьвсе его дочерние комментарии, а затем просто продолжайте переходить вниз, чтобы получить каждый отдельный дочерний комментарий.Однако у меня возникают проблемы с реализацией этого, когда дело доходит до получения данных из представления в шаблон.

Я хочу, чтобы было возможно иметь бесконечное количество дочерних комментариев, потому что кто знает, как долгообсуждение продлится, и я не хочу произвольно ограничивать его.Проблема, с которой я столкнулся, заключается в том, чтобы вы могли получить все эти комментарии из представления к шаблону, не теряя их связь с родительским комментарием?

В настоящее время так выглядит psuedocode для моего кода:

#the view
def comment_page(request, forum, comment_id):
   #this is the main comment that all others will stem from
   main_comment = Comment.objects.get(id=comment_id)
   children_comments = main_comment.comment_set.all()

#the template
{% for comment in children_comments %}
  <p class='comment'>{{comment}}</p>
{% endfor %}

Очевидно, что я даже не пытаюсь получить здесь все дочерние комментарии, он просто получает дочерние комментарии в самом первом посте.Чего я не понимаю, так это как я могу затем просмотреть каждый из этих дочерних комментариев, а затем получить все их комментарии и продолжать делать это для каждого нового комментария?

Наиболее разумно сделать это втак как я могу использовать API QuerySet Django там, но я не понимаю, как я смогу передать все комментарии к шаблону, не потеряв их отношения с родителем.Единственная идея, о которой я могу подумать, - это просмотреть все комментарии в представлении и создать строку html, которую я просто пропускаю и просто отображаю в шаблоне, но это кажется ужасной идеей, потому что она имеет дело ссвязанные с шаблоном вещи в представлении.

Ответы [ 2 ]

1 голос
/ 10 мая 2011

Возможно, вы захотите использовать MPTT, например django-mptt


это может быть реализовано с помощью специального фильтра с inclusion_tag, который включает в себя, но вызывает много запросов к вашей базе данных:

@register.inclusion_tag('children.html')
def comments_tree(comment):
    children = comment.comment_set.all()
    return {'children': children}

# children.html

<ul>
    {% for child in children %}
    <li> <a href="{{ child.get_absolute_url }}">{{ child }}</a></li>
        {% if child.comment_set.count > 0 %}
        {% comments_tree child %}
        {% endif %}
    {% endfor %}
</ul>

# your template

{% comments_tree comment %}

Этот старый вопрос, вероятно, представляет интерес:

Как отобразить древовидную структуру (рекурсивную) с использованием шаблона django?

0 голосов
/ 10 мая 2011

Редактировать : для будущих читателей не делайте этого, поскольку внутренняя переменная for цикла comment не заменяет внешнюю переменную comment во время выполнения цикла, что приводит к бесконечной рекурсии. / Edit

Если вам нужна рекурсивная древовидная структура на вашей HTML-странице (т. Е. Набор вложенных тегов <div>), вы можете написать рекурсивный шаблон «комментария».

Пример : (не проверено)

{# comment.html #}
<p class='comment'>{{ comment.text }}</p>
{% if comment.children %}
   {% for comment in comment.children %}
      {% include "comment.html" %}
   {% endfor %}
{% endfor %}

Цикл for связывает переменную шаблона comment с каждым дочерним элементом перед включением самого себя.

Производительностьпримечание : Если ваши наборы комментариев часто бывают короткими, это, вероятно, будет очень медленным.Я рекомендую сделать ваши комментарии недоступными для редактирования и кэшировать результат!

Альтернативное решение : если вам не нужны рекурсивные теги HTML <div>, вы можете написать генератор, которыйвыполняет обход структуры по предварительному заказу и выдает (depth, comment) пар.Скорее всего, это будет намного более эффективным в скорости рендеринга.

...