Ошибка кругового импорта при использовании wagtail-generi c -chooser - PullRequest
1 голос
/ 29 марта 2020

Я использую wagtails wagtail-generi c -chooser для создания customChoosers для моих моделей данных, и он отлично работает, когда я ссылаюсь на другие модели modelAdmin.

Однако я столкнулся с ситуацией, когда у меня есть модель Lexis с полем, которое имеет ссылку FK на себя. Идея состоит в том, чтобы иметь термин Lexis, и тогда с ним могут быть связаны связанные термины lexis. Он работает нормально с обычной FieldPanel, но это не очень хороший интерфейс, когда есть сотни лексических терминов. Соответственно, я хотел создать собственный LexisChooser для этого поля. Однако проблема, с которой я столкнулся, заключается в том, что в соответствии с документацией для создания функционального виджета мне необходимо создать как представление, так и adminChooser, который ссылается на модель, к которой подключен ChooserPanel.

https://github.com/wagtail/wagtail-generic-chooser#chooser на основе модели виджетов

Однако это имеет смысл, когда я затем пытаюсь импортировать свой LexisChooser в свою модель Lexis, чтобы использовать LexisChooser в качестве виджет, я получаю ошибку ниже.

ImportError: невозможно импортировать имя 'Lexis' из 'lexis.models'

Я понимаю, что это связано с ошибкой кругового импорта, поскольку у меня есть подклассы, которые импортируют класс Lexis для того, чтобы создайте виджет LexisChooser, а затем я пытаюсь импортировать этот виджет в класс Lexis.

Я знаю, что это не ошибка с Wagtail и не проблема с wagtail-generi c -chooser. Однако у кого-нибудь есть идеи, как я могу реорганизовать код, чтобы сделать эту функцию такой, чтобы Я могу использовать LexisChooser на поле модели Lexis.

Ниже мой код.

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"

Это, к сожалению, приводит к циклической ошибке импорта: ImportError: невозможно импортировать имя 'Lexis' из 'lexis.models'

При исследовании этого Ошибка: я обнаружил, что люди рекомендуют импортировать Lexis внутри класса по мере необходимости, а не вверху каждого файла, но, похоже, это не работает с подклассами, как описано выше, потому что я получаю ту же ошибку.

Если у вас есть какие-либо идеи о том, как я могу реорганизовать код, чтобы он работал, а не создавать ошибку циклического импорта, это было бы очень полезно.

Я бегу Django 3, python 3.7, трясогузка 2.8

Спасибо

1 Ответ

0 голосов
/ 29 марта 2020

Разделите файл модели на два отдельных файла, содержащих Lexis и LexisLink, , как показано в документации.

Тогда LexisLink может указывать на LexisChooser, пока он чисто относится к модели Lexis.

...