Django:管理界面中没有显示父类别

时间:2017-11-14 11:28:28

标签: python django django-models django-admin

问题: 短划线标志显示在“父类别”中。我打开任何菜单项之前的列。我得到了父母类别'打开菜单项配置文件时的项目(请参阅下面的admin.py

在打开菜单配置文件之前和之后:picture1picture2(注意“父类别”列)

我的models.py(关注parent_id

class Menu(models.Model):

    cat_title = models.CharField(max_length=150, verbose_name='Category title')
    menu_title = models.CharField(max_length=150, verbose_name='Menu title')
    parent_id = models.IntegerField(blank=True, null=True, verbose_name='Parent category', choices=(('',''),))
    url = models.CharField(max_length=255, verbose_name='URL', blank=True)
    named_url = models.CharField(max_length=255, verbose_name='Named URL', blank=True)
    level = models.IntegerField(default=0, editable=False)

我的admin.py()

class MyMenu(admin.ModelAdmin):

    def get_choices(self):
        choices = (('',''),)
        categories = models.Menu.objects.all().values()
        for i in categories:
            choices += ((i['id'], i['cat_title']),)
        return choices

    def formfield_for_choice_field(self, db_field, request):
        if db_field.name == 'parent_id':
            db_field.choices = self.get_choices()

        return super().formfield_for_choice_field(db_field, request)
    list_display = ('cat_title', 'menu_title', 'parent_id', 'level')
    list_display_links = ('cat_title', 'menu_title')

    admin.site.register(models.Menu, MyMenu)

问题:如何在不打开任何菜单项配置文件的情况下重写admin.py以显示parent_id项目?

我已经尝试Model.get_FOO_display(),但它没有以正确的方式运作。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

在不更改模型的情况下,最简单的解决方案可能是在管理员中添加parent方法并使用它而不是" parent_id"在list_display列表中:

class MyMenu(admin.ModelAdmin):
    # ....
    def parent(self, obj):
        if obj.parent_id:
            return Menu.objects.get(pk=obj.parent_id).cat_title
        return ""

    list_display = ('cat_title', 'menu_title', 'parent', 'level')


    # Unrelated but you may also want to rewrite `get_choices`
    # in a simpler and more performant way:
    def get_choices(self):
        choices = models.Menu.objects.values_list("id", "cat_title"))
        return (('',''),) + tuple(choices) 

或者在parent型号上设置Menu方法或属性:

class Menu(models.Model):
    # ...

    # you may want to use django's `cached_property` instead
    # but then you'll have to invalidate the cache when setting
    # (or unsetting) `.parent_id`
    @property
    def parent(self):
        if not self.parent_id:
            return None
        return Menu.objects.get(pk=self.parent_id)

并添加" parent"致你的管理员list_display

但由于Menu.parent_id实际上是Menu上的外键,因此正确的解决方案是在模型中声明它:

class Menu(models.Model):
    cat_title = models.CharField(max_length=150, verbose_name='Category title')
    menu_title = models.CharField(max_length=150, verbose_name='Menu title')
    parent = models.ForeignKey("self", blank=True, null=True, related_name="children")
    # etc