Вот что я изменил по сравнению с предыдущим показом.
Создание дерева было реализовано в моделе комментариев, путем получения разными запросами родительских и вложенных комментариев.
Я перенес создание дерева во вюху (пока что), как советовал lampslave.
Вот как это работает:
р
def filter_by_instance(self, instance):
content_type = ContentType.objects.get_for_model(instance.__class__)
object_id = instance.id
qs = super(CommentManager, self).filter(content_type=content_type, object_id=object_id)
return qs
Получаем все комментарии для поста:
comments = Comment.objects.filter_by_instance(post).select_related()
Обязательно нужно использовать .select_related() для получения связанных моделей.
SQL запрос без .select_related()
SELECT ••• FROM "comments" WHERE ("comments"."object_id" = '1' AND "comments"."content_type_id" = '7') ORDER BY "comments"."date" ASC
с ним
SELECT ••• FROM "comments" INNER JOIN "django_content_type" ON ("comments"."content_type_id" = "django_content_type"."id") INNER JOIN "auth_user" ON ("comments"."user_id" = "auth_user"."id") WHERE ("comments"."content_type_id" = '7' AND "comments"."object_id" = '1') ORDER BY "comments"."date" ASC
Сортируем комментарии нулевого и первого уровней
comments_parent = []
comments_children = []
for comment in comments:
if comment.parent_id is None:
comments_parent.append(comment)
else:
comments_children.append(comment)
Выводим в шаблоне(тут конечно минус что много логики в шаблоне):
{% for comment in comments_parent %}
<div id="comment-{{ comment.id }}" class="card p-3">
<blockquote class="card-block card-blockquote">
<div>
<small class="text-muted">
{{ comment.user }} <cite title="Source Title">{{ comment.date|timesince }} назад</cite>
</small>
</div>
<p>{{ comment.content }}</p>
</blockquote>
<form method="POST" action="">
{% csrf_token %}
{{ comment_form }}
<input type="hidden" name="parent_id" value="{{ comment.id }}">
<p><input type="submit" class="btn btn-primary btn-comment" value="Ответить"></p>
</form>
</div>
{% for child_comment in comments_children %}
{% if child_comment.parent_id == comment.id %}
<div id="comment-{{ child_comment.id }}" class="reply card p-3">
<blockquote class="card-block card-blockquote">
<div>
<small class="text-muted">
{{ child_comment.user }} <cite title="Source Title">{{ child_comment.date|timesince }} назад</cite>
</small>
</div>
<p>{{ child_comment.content }}</p>
</blockquote>
<form method="POST" action="">
{% csrf_token %}
{{ comment_form }}
<input type="hidden" name="parent_id" value="{{ comment.id }}">
<p><input type="submit" class="btn btn-primary btn-comment" value="Ответить"></p>
</form>
</div>
{% endif %}
{% endfor %}
{% endfor %}
В итоге выходит мы получаем все данные с базы для комментариев 1 запросом, потом сортируем по вложенности и выводим в шаблоне.
Updated 13 June 2017, 8:14 by ModPhoenix.