Списък с вложени разговори с 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, така че Threads могат да станат деца на други Threads.

Мога да правя неща като -

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

Да, наличието на конструктор само за това е лош дизайн. Статичен SetPath метод, който може да бъде извикан само веднъж (в противен случай хвърля изключение), би изглеждал по-добър. Бихте задали пътя по време на стартиране на приложение и т.н.

След това можете или да го направите static class, или сингълтон, ако се изисква да удовлетвори някакъв сценарий, базиран на интерфейс.

Следва: вие трябва да добавите синхронизация тук! Това не е безопасно за нишки. Ако две нишки се опитат да се регистрират едновременно, бих очаквал това да се срине ужасно. Не е необходимо да е сложно; най-просто:

private readonly object syncLock = new object();
public static void Log(string value) {
    lock(syncLock) {
        //...
    }
}

(но имайте предвид, че това може да доведе до някои разходи за блокиране; които могат да бъдат подобрени с по-сложен код - вижте по-долу)

Има съществуващи библиотеки за регистриране, които ще решат много повече проблеми - разделяне на файлове, async (за да спре кодът ви да бъде блокиран от IO), групиране и т.н.; защо просто не използвате един от тях? По-специално, в този момент вашият файл няма да бъде напълно затворен при излизане от приложението, не се изтрива редовно и ще държи файла заключен през повечето време. Не е добре.

  -  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() ]

Този вид нещо връща списък от 2-кортежи за всяка нишка и всички нейни отговори.

Ако отговорът няма спомагателни нишки, последващият списък е празен. Това може да стане тромаво, така че някои хора обичат да го оптимизират.

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