Вложенный список бесед с django

Привет у меня есть такая модель

def Photo(models.Model):
    # Photo object fields...

def PhotoThread(models.Model):
    photo = models.ForeignKey(Photo)
    message = models.TextField(blank=True)
    reply_to = models.ForeignKey('self', related_name='replies', null=True, blank=True)
    votes = models.IntegerField()

Как видите, объект Thread имеет поле reply_to, так что потоки могут стать дочерними элементами других потоков.

Я могу делать такие вещи, как -

photo = Photo.objects.get(pk=1)
threads = photo.photothread_set.all()

Это приведет к тому, что потоки будут привязаны к фотографии, однако эта система позволяет ответам также иметь ответы.

Как мне перебрать все ответы и получить ответы на них (вплоть до максимального количества ответов, которые у нас есть).

Я хочу отобразить это как вложенный список HTML. Также я хочу иметь возможность упорядочивать все темы и ответы в поле «голоса».

Спасибо


person dotty    schedule 25.11.2010    source источник
comment
Есть несколько способов составить такой список. Пожалуйста, предоставьте пример списка, который точно показывает, какую структуру вы хотите.   -  person S.Lott    schedule 25.11.2010
comment
Обновите свой вопрос, пожалуйста. Не добавляйте комментарии. Исправьте вопрос.   -  person S.Lott    schedule 25.11.2010
comment
В зависимости от размера ваших потоков этот подход может быть довольно медленным. Ознакомьтесь с django-mptt, чтобы узнать о более эффективном способе обработки деревьев с помощью Django code.google.com/ p/django-mptt   -  person Daniel Hepper    schedule 25.11.2010


Ответы (2)


Напишите тег шаблона включения, который использует себя в своем шаблоне.

person Ignacio Vazquez-Abrams    schedule 25.11.2010
comment
Неа. Но это действительно не очень сложно. Просто сделайте {% load %} в верхней части шаблона и перейдите через replies для текущего сообщения. - person Ignacio Vazquez-Abrams; 25.11.2010
comment
Окис, я тебя понял. Я попробую написать собственный тег шаблона. - person dotty; 25.11.2010
comment
Я изо всех сил пытаюсь заставить это работать, у вас есть образец, чтобы я начал? - person dotty; 25.11.2010

Добро пожаловать в рекурсию. Вот обычное решение

def thread_plus_replies( someThread ):
    return someThread, [ thread_plus_replies(r) for r in someThread.replies.ordered('votes').all() ]

Такого рода вещи возвращают список из двух кортежей для каждого потока и всех его ответов.

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

def thread_plus_replies( someThread ):
    if len(someThread.replies) == 0:
        return someThread
    return someThread, [ thread_plus_replies(r) for r in someThread.replies ]

Придерживаясь первого, каждый поток представляет собой 2-кортеж. Мы можем украсить 2-кортеж с помощью HTML.

def make_html( thread_results ):
    head, tail = thread_results
    return "<ul><li>{0}</li><li>{1}</li></ul>".format( head, make_html(tail) )

Это даст вам вложенные теги <ul> для ваших вложенных потоков.

person S.Lott    schedule 25.11.2010
comment
Куда должен идти этот код? В рамках модели как метода? или как тег шаблона? - person dotty; 25.11.2010
comment
и является ли thread_results в третьей функции результатом Thread.objects.all() ? - person dotty; 25.11.2010
comment
@dotty: Куда должен идти этот код? Функции просмотра. thread_results в третьей функции является результатом Thread.objects.all() ?. Нет. Даже не близко. Это результаты thread_plus_replies: два кортежа ветки и ответы на эту ветку. - person S.Lott; 25.11.2010
comment
Это то, что у меня есть pastie.org/1326181, однако его создание объекта "функция" не имеет атрибута " ответы 'любые идеи? - person dotty; 25.11.2010
comment
Я обновил свой вопрос реальным представлением моих моделей. - person dotty; 25.11.2010
comment
@dotty: объект «функция» не имеет атрибута «ответы». Правильно. Ваша модель говорит «reply_to». Тем не менее, в моих примерах используются «ответы». Интересно, что вам нужно подумать, чтобы сопоставить мой ответ с вашей новой (и меняющейся) моделью. Это нормально думать. Это лучше, чем копировать и вставлять. Действительно. - person S.Lott; 26.11.2010
comment
Хорошо, я на самом деле использовал метод Игнасио Васкеса-Абрамса для написания шаблонного фильтра, и я заставил его работать на удивление хорошо. Спасибо за ответ, однако, научил меня функции формата Python. - person dotty; 26.11.2010