Самореферентные отношения Джанго?

Я пытаюсь создать страницу модели, страница также должна иметь «дочерние страницы».

Код моей модели, приведенный ниже, поддерживает сбой Python на моем Mac (python 2.6.1) и Ubuntu 10.04 (python 2.6.5):

from django.db import models
from django.contrib import admin

class Page(models.Model):
    slug = models.SlugField(blank=True)
    title = models.CharField(max_length=100)
    content = models.TextField(blank=True)
    children = models.ManyToManyField("self", blank=True)
    published = models.BooleanField(default=True)
    created = models.DateTimeField(blank=True, auto_now_add=True)

    def html(self):
        html = "<li>"
        html += self.title

        children = self.children.all()
        if len(children) > 0:

            for page in children:
                html += page.html()

        html += "</li>"
        return html

    def __unicode__(self):
        return self.title


class PageAdmin(admin.ModelAdmin):
    prepopulated_fields = {'slug': ('title',)}


admin.site.register(Page, PageAdmin)

Что я делаю не так? Или этот своего рода HTML-рендеринг относится к представлениям?

Спасибо.


person Community    schedule 28.12.2010    source источник
comment
Количество вызовов PyEval_EvalFrameEx в трассировке стека могло привести к переполнению стека. Очень похоже на ошибку Python, потому что обычно Python прерывает рекурсию в какой-то момент с помощью RuntimeError: maximum recursion depth exceeded.   -  person AndiDog    schedule 28.12.2010
comment
Небольшой комментарий к вашей модели: отношение «многие ко многим», вероятно, является неправильным представлением. В дереве узел (или в вашем коде страница) имеет только ноль или одного родителя. Внешний ключ parent был бы лучшим представлением.   -  person Benjamin Wohlwend    schedule 28.12.2010
comment
@piquadrat Спасибо, что заметили. Я виню сонливость.   -  person    schedule 28.12.2010


Ответы (2)


Я предлагаю вам использовать django-mptt, который предлагает более простой в использовании метод рекурсивного выплевывания структуры.

Однако сначала необходимо зарегистрировать mptt с моделью .

Вот мой код, использующий его: Включая количество внешних ключей в список полного дерева django mptt?

person meder omuraliev    schedule 28.12.2010
comment
Отлично работает и прост в использовании. Спасибо. - person ; 28.12.2010

Что касается самой модели, вы просто думаете об этом в неправильном направлении. Вместо

children = models.ManyToManyField("self", blank=True)

использовать

parent = models.ForeignKey("self", blank=True, related_name="children")

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

Рендеринг HTML обычно должен происходить в представлениях, а не в модели. Используйте mptt, как предлагает meder.

person Jordan Reiter    schedule 28.12.2010