使用 wagtail-generic-chooser 循环导入错误

Circular importing error using wagtail-generic-chooser

我正在使用 wagtails wagtail-generic-chooser 为我的数据模型创建 customChooser,每当我引用其他 modelAdmin 模型时它都运行良好。

但是,我遇到过这样一种情况,我有一个 Lexis 模型,其字段本身具有 FK link。这个想法是有一个 Lexis 术语,然后可以有相关的词汇术语连接到它。它与普通的 FieldPanel 一起工作正常,但是当有数百个词汇术语时,这不是一个很好的 UI 体验。因此,我想为该字段创建一个自定义 LexisChooser。但是,根据文档,我 运行 遇到的问题是为了创建一个功能性小部件,我需要创建一个视图和 adminChooser 来引用 ChooserPanel 连接到的模型。

https://github.com/wagtail/wagtail-generic-chooser#chooser-widgets-model-based

这是有道理的,但是,当我随后尝试将 LexisChooser 导入 Lexis 模型以将 LexisChooser 用作小部件时,出现以下错误。

ImportError: 无法从 'lexis.models'

导入名称 'Lexis'

我意识到这是由于循环导入错误问题,因为我有子classes 正在导入 Lexis Class 以构建 LexisChooser 小部件,然后我正在尝试导入将该小部件放入 Lexis Class。

我知道这不是 Wagtail 的错误,也不是 wagtail-generic-chooser 的问题,但是,有没有人知道我如何重构代码来实现此功能,以便我可以使用Lexis 模型字段上的 LexisChooser。

下面是我的代码。

views.py 创建视图

from django.utils.translation import ugettext_lazy as _
from generic_chooser.views import ModelChooserViewSet
from lexis.models import Lexis

class LexisChooserViewSet(ModelChooserViewSet):

    icon = 'user'
    model = Lexis
    page_title = _("Choose A Lexis Term")
    per_page = 20
    order_by = 'term'
    fields = ['term']

wagtail_hooks.py 注册查看

from wagtail.core import hooks
from .views import LexisChooserViewSet

@hooks.register('register_admin_viewset')
def register_lexis_chooser_viewset():
    return LexisChooserViewSet('lexis_chooser', url_prefix='lexis-chooser')

widgets.py 创建一个小部件

from django.utils.translation import ugettext_lazy as _
from generic_chooser.widgets import AdminChooser
from lexis.models import Lexis

class LexisChooser(AdminChooser):

     choose_one_text = _('Choose a Lexis')
     choose_another_text = _('Choose another Lexis')
     link_to_chosen_text = _('Edit this Lexis')
     model = Lexis
     choose_modal_url_name = 'lexis_chooser:choose'

lexis/models.py 使用小部件

from django.db import models
from modelcluster.fields import ParentalKey
from wagtail.admin.edit_handlers import FieldPanel, InlinePanel
from wagtail.core.models import Orderable
from modelcluster.models import ClusterableModel
from chooser_panels.widgets import LexisChooser


# Orderable link to multiple other linked lexis terms
class LexisLink(Orderable):

    page = ParentalKey("lexis.Lexis", related_name="lexis_link")

    term_link = models.ForeignKey(
        'lexis.Lexis', 
        on_delete=models.SET_NULL, 
        related_name='term_linked', 
        null=True
    )

    panels = [
        FieldPanel("term_link", widget=LexisChooser)
    ]


class Lexis(ClusterableModel):

    template = "lexis/lexis_page.html"
    term = models.CharField(max_length=100, blank=True, null=True)
    panels = [
        FieldPanel("term"),
        InlinePanel('lexis_link', label='Linked Lexis Terms'), 
    ]

    def __str__(self):
        return self.term

    class Meta:
        verbose_name = "Lexis"
        verbose_name_plural = "Lexis"

不幸的是,这会导致循环导入错误: 导入错误:无法从 'lexis.models'

导入名称 'Lexis'

在研究这个错误时,我发现人们建议根据需要在 class 中导入 Lexis 而不是在每个文件的顶部,但这似乎不适用于 subclass 如上所述,因为我得到了同样的错误。

如果您对我如何重构代码以使其正常工作而不造成循环导入错误有任何想法,我们将不胜感激。

我是运行宁 姜戈3, python 3.7, 鹡鸰 2.8

谢谢

将您的模型文件拆分为两个单独的文件,其中包含 LexisLexisLinkas demonstrated in the documentation.

然后LexisLink可以引用LexisChooser,而它干净利落地引用了Lexis模型。