2010-12-28 13 views
6

私はモデルページを作成しようとしていますが、ページも "子ページ"を持つことができます。Djangoの自己参照関係ですか?

下のマイモデルコードは、私のMac(のpython 2.6.1)とUbuntu 10.04(のpython 2.6.5)にcrashing Pythonを保持:

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レンダリングはビューに属していますか?

ありがとうございました。再帰的な構造を吐き出し方法を使いやすく提供しています

+0

スタックトレース中の 'PyEval_EvalFrameEx'呼び出しの数がスタックオーバーフローを引き起こした可能性があります。通常Pythonは 'RuntimeError:maximum recursion depth exceeded 'を使ってある時点で再帰を中断するため、Pythonのバグによく似ています。 – AndiDog

+0

あなたのモデルに対する少しのコメント:多対多の関係はおそらく間違った表現です。ツリー内では、ノード(またはコード内のページ)には0個または1個の親しかありません。外部キー「親」がより良い表現になります。 –

+0

@piquadrat気づいてくれてありがとう。私は眠気を責める。 – jussi

答えて

13

は、ここでそれを使用して私のコードです。代わりに

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

使用

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

のこれは、ページ・レコードから直接子どもにアクセスできるようになりますが、データベースでより簡単な表現でなければなりません。

HTMLレンダリングは一般的に、モデルではなくビューで実行する必要があります。メディエが示唆するようにmpttを使用してください。