【问题标题】:Multiple ModelAdmins for one Wagtail model一个 Wagtail 模型的多个 ModelAdmins
【发布时间】:2019-12-19 02:51:29
【问题描述】:

假设我有一个模型:

class BlogPost(Page):

date = models.DateField("Post date")
intro = models.CharField(max_length=250)
body = StreamField([
    ('paragraph', blocks.RichTextBlock()),
    ('image', ImageChooserBlock()),
    ('gallery', CarouselBlock()),
    ('video', EmbedBlock()),
])
...

我想在侧边栏中创建与此模型相关的多个页面。我尝试了这样的方法:

    class BlogPostAdmin(ModelAdmin):
        model = BlogPost
        ...

    class DraftPostAdmin(ModelAdmin):
        model = BlogPost
        #query for drafts
        ...

    class ScheduledPostAdmin(ModelAdmin):
        model = BlogPost
        #query for scheduled posts
        ...

    class BlogGroup(ModelAdminGroup):
        menu_label = 'Blog'
        items = (BookAdmin, AuthorAdmin, GenreAdmin)
        ...

    modeladmin_register(BlogGroup)

但问题是所有页面都显示与第一个 ModelAdmin 的查询集匹配的模型实例。在 Wagtail 中实现多个菜单项以管理一个模型的不同方面的最佳方法是什么?

【问题讨论】:

    标签: python django wagtail


    【解决方案1】:

    使用proxy model,然后为每个代理模型定义一个适当的manager。我在现有的基于 Wagtail 的应用程序中进行了这项工作,在该应用程序中,我为会员应用程序中的各种会员状态定义了代理模型。在我的例子中,基本模型是 Member,但我有 CurrentMemberNonCurrentMember 等。This comment 和相关讨论可能也很有趣。

    【讨论】:

      【解决方案2】:

      这是一种稍微不同的方法,通过覆盖 BlogGroup 上的一些方法并仅使用一个 BlogPostAdmin,您可以走得更远。

      代码

      from wagtail.admin.menu import MenuItem
      
      from wagtail.contrib.modeladmin.options import (
          ModelAdmin, ModelAdminGroup, modeladmin_register)
      
      from bakerydemo.blog.models import BlogPage
      
      class ModelAdminQueryMenuItem(MenuItem):
          # based on the `ModelAdminMenuItem` but extends the Wagtail Admin `MenuItem` directly.
      
          def __init__(self, model_admin, order, query, label_append=''):
              self.model_admin = model_admin
              url = model_admin.url_helper.index_url + "?" + query
              classnames = 'icon icon-%s' % model_admin.get_menu_icon()
              super().__init__(
                  label=model_admin.get_menu_label() + label_append,
                  url=url,
                  classnames=classnames,
                  order=order
              )
      
          def is_shown(self, request):
              return self.model_admin.permission_helper.user_can_list(request.user)
      
      
      class BlogPageAdmin(ModelAdmin):
          model = BlogPage
      
          def get_menu_items(self, order=None):
              # new class method that builds a list of menu_item(s)
              menu_items = []
      
              ## build 'live only' (no unpublished changes) items
              live_menu_item = ModelAdminQueryMenuItem(self, order or self.get_menu_order(), query='has_unpublished_changes=False', label_append=' (Live)')
              menu_items.append(live_menu_item)
      
              ## build 'draft' items
              draft_menu_item = ModelAdminQueryMenuItem(self, order or self.get_menu_order(), query='has_unpublished_changes=True', label_append=' (Draft)')
              menu_items.append(draft_menu_item)
      
              return menu_items
      
          def get_queryset(self, request):
              qs = super().get_queryset(request)
              ## read the request and modify the qs as needed if query param does not work easily
              return qs
      
      class BlogGroup(ModelAdminGroup):
          menu_label = 'Blog'
          items = (BlogPageAdmin, )
      
          def get_submenu_items(self):
              menu_items = []
              item_order = 1
              for modeladmin in self.modeladmin_instances:
                  menu_items = menu_items + modeladmin.get_menu_items(item_order)
                  item_order = len(menu_items) + 1
              return menu_items
      
      modeladmin_register(BlogGroup)
      
      

      说明

      • 设置一个 BlogPageAdmin 类,这将有一个新方法 get_menu_items(复数),它将返回 Wagtail 菜单项列表。
      • 我们通过覆盖 Wagtail 管理类 MenuItem 来生成这些菜单项,但我们还添加了一个用户权限助手,请参阅 modeladmin 中的 menus.py 助手文件。这为我们提供了一种自定义 URL(添加 url 参数)和标签的方法,可以根据需要对其进行修改,以使我们的子菜单项呈现我们想要的方式。
      • get_menu_items 手动构建我们想要的所有菜单项,我们可以在此处自定义任何内容,包括标签和图标以显示您想要的内容,尽管这只是提供了一种将自定义查询参数字符串传递给构建的 url 的方法向上。
      • 查询参数可以是我们想要的任何内容,搜索字符串和Page 上的许多字段无需任何代码更改即可使用,因为它们只是作为字典传递到我们的查询中。下面我列出了所有可能的值。
      • 对于其他更具体的内容,我们需要重写方法 get_queryset 并读取请求参数并相应地更新我们的查询。
      • 您需要自定义视图的页面标题,但这可以通过阅读视图模板自定义中的请求或进一步自定义构建的 url 来完成。
      • 最后,在我们的BlogGroup 中,我们覆盖get_submenu_items 以使用自定义方法get_menu_items。请注意,这假设传入该组的每个模型都具有该方法。

      查询字符串字段

      • 选择有:blog_person_relationship、body、content_type、content_type_id、date_published、depth、draft_title、expire_at、expired、first_published_at、formsubmission、go_live_at、group_permissions、has_unpublished_changes、id、image、image_id、介绍、last_published_at、latest_revision_created_at、live、live_revision、 live_revision_id,锁定,numchild,所有者,owner_id,page_ptr,page_ptr_id,路径,重定向,修订,search_description,searchpromotion,seo_title,show_in_menus,sites_rooted_here,slug,副标题,tagged_items,标签,标题,url_path,view_restrictions

      【讨论】:

        猜你喜欢
        • 2011-01-14
        • 2011-06-10
        • 2018-03-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多