Django自引用模型作为管理站点中的多对多内联树

时间:2011-11-30 11:45:05

标签: django django-admin django-forms

假设我在models.py中有以下模型:

class Category(models.Model):
    name = models.CharField(max_length=128)
    parent = models.ForeignKey('self', null=True, blank=True)

class Item(models.Model):
    name = models.CharField(max_length=128)
    categories = models.ManyToManyField(Category, related_name='categories')

class Membership(models.Model):
    category = models.ForeignKey(Category)
    item = models.ForeignKey(Item)
    date_assigned = models.DateField()

而且,正如Working with many-to-many intermediary models中所述,我在admin.py

中有这个
class MembershipInline(admin.TabularInline):
    model = Membership
    extra = 3

class CategoryAdmin(admin.ModelAdmin):
    inlines = (MembershipInline,)

class ItemAdmin(admin.ModelAdmin):
    inlines = (MembershipInline,)

在管理网站中创建Item时,确实会呈现类别内联表单,但仅仅是<select>窗口小部件,这有点麻烦,因为每个类别都显示在同一级别。

我怎样才能将这些呈现为树木?我不需要非常花哨的东西,选择中的一些缩进就可以了。

我尝试使用django-mpttdjango-treebeard,但他们似乎没有涉及内联中介多对多模型案例。

2 个答案:

答案 0 :(得分:2)

如果您使用mptt注册Item模型。您可以覆盖unicode方法:

class Item(models.Model):

    ...  

    def __unicode__(self):
         return '%s%s' % ('  ' * self.level, super(MarkerCategory, self).__unicode__())

如果您想要更清晰的解决方案,则应覆盖该表单,并更改窗口小部件并在此特定窗口小部件中执行此逻辑。

答案 1 :(得分:0)

我讨厌浏览器“聪明”。

from django.utils.safestring import mark_safe

...

class Item(models.Model):

    ...  

    def __unicode__(self):
         return mark_safe('%s%s' % ('&nbsp;' * 4 * self.level,
                          super(Item, self).__unicode__()))

但我建议这个逻辑在指定小部件