代码之家  ›  专栏  ›  技术社区  ›  Roman Kozinets

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

  •  0
  • Roman Kozinets  · 技术社区  · 7 年前

    问题: 在我打开任何菜单项之前,“父类别”列中会显示短划线标志。打开菜单项配置文件时,我会得到“父类别”项(请参见 admin.py 以下)

    打开菜单配置文件前后: picture1 picture2

    我的 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)
    

    管理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)
    

    问题: 我怎么能重写我的 显示 父项id 没有打开任何菜单项配置文件的项目?

    我已经试过了 Model.get_FOO_display() 但它并没有以正确的方式工作。任何帮助都将不胜感激。

    1 回复  |  直到 7 年前
        1
  •  1
  •   bruno desthuilliers    7 年前

    在不改变模型的情况下,最简单的解决方案可能是添加一个 parent 方法,并使用它而不是 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) 
    

    或使 父母亲 您的 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)
    

    列表显示 .

    但是自从 Menu.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 = models.ForeignKey("self", blank=True, null=True, related_name="children")
        # etc