【问题标题】:Can I use a recursive ParentalKey in Wagtail?我可以在 Wagtail 中使用递归 ParentalKey 吗?
【发布时间】:2020-11-29 16:55:14
【问题描述】:

假设我在 Wagtail 应用中有以下模型:

# models.py
from django.db import models
from django.db.models.deletion import CASCADE

from wagtail.admin.edit_handlers import InlinePanel, FieldPanel

from modelcluster.models import ParentalKey, ClusterableModel


class Person(ClusterableModel):
    name = models.CharField(max_length=300)
    contact_for = ParentalKey(
        'self', on_delete=CASCADE, null=True, related_name='contacts'
    )

    panels = [
        FieldPanel('name'),
        FieldPanel('contact_for'),
        InlinePanel('contacts')
    ]

还有以下钩子:

# wagtail_hooks.py
from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register
from home.models import Person


class PersonAdmin(ModelAdmin):
    model = Person
    menu_label = 'People'
    menu_icon = 'list-ul'
    menu_order = 200
    add_to_settings_menu = False
    exclude_from_explorer = False
    list_display = ('name',)
    search_fields = ('name',)
    list_filter = ('contact_for',)


modeladmin_register(PersonAdmin)

当运行上述并导航到 Admin > People > Add Person 我会得到一个 RecursionError 异常(超出最大递归深度)。

我猜这是与 Wagtail 相关的问题,因为我可以在 IPython 中使用该类:

./manage.py shell -i ipython

In [1]: from home.models import Person

In [2]: mike = Person(name='Mike')

In [3]: mike.contacts = [Person(name='Sam'), Person(name='John')]

In [4]: mike.contacts
Out[4]: <modelcluster.fields.create_deferring_foreign_related_manager.<locals>.DeferringRelatedManager at 0x7f36e9548af0>

In [5]: mike.save()

In [6]: [person.name for person in Person.objects.all()]
Out[6]: ['Mike', 'Sam', 'John']

In [7]: Person.objects.all()[1].contact_for.name
Out[7]: 'Mike'

那么,有没有办法可以在 Wagtail 中使用递归 ParentalKey?我做错了什么/错过了什么?

编辑:我刚刚找到this answer。所以我想知道我是否应该尝试将 ParentalKey(和 ParentalManyToManyField)用于非 Page 模型。

编辑 2:对于任何感兴趣的人,我最终拆分了我的模型以避免递归键。 InlinePanels 确实与 ModelAdmin 类一起使用,只是 Wagtail 不似乎支持递归键。我还选择在合适的地方使用 Snippets 和 SnippetChooserPanel。

【问题讨论】:

    标签: wagtail


    【解决方案1】:

    ParentalKey 表示子模型在理论上被视为父模型的“一部分”,并且不作为独立实体存在 - 例如,作为页面一部分的图片库 - 用于版本控制等目的,以及审核工作流程。 (在 Wagtail 中,通过 sn-ps 或 ModelAdmin 处理的非页面模型没有这些功能,但为了让它们与页面共享相同的 InlinePanel 机制,它们也使用 ParentalKey。)

    在这种情况下,一个 Person 不是另一个 Person 的一部分,并且需要独立于“父级”进行编辑,因此 ParentalKey 在这里不合适。相反,您应该使用 ForeignKey,它只是表示模型之间的某种关系。这确实意味着您不能使用 InlinePanel 在同一视图中管理多个 Person 记录 - 您必须分别编辑它们,并使用 SnippetChooserPanel 之类的东西或简单的下拉菜单来设置它们之间的关系。

    【讨论】:

      猜你喜欢
      • 2022-06-25
      • 2010-09-20
      • 2015-12-30
      • 2019-04-18
      • 1970-01-01
      • 2023-03-13
      • 2022-06-29
      • 2017-12-31
      • 2011-02-08
      相关资源
      最近更新 更多