使用外键集编辑站点设置时生成 KeyError
KeyError generated when editing site setting with foreign key set
Django 版本:2.1.5
Python版本:3.6.8
鹡鸰版本: 2.4
我有一个模板,其页脚中有四列 link。我已经为 link 的每一列设置了以下模型,其中包含一个 BaseSetting
对象和页脚 link 对象。页脚 link 对象每个 ForeignKey
到 TemplateItems
对象。
@register_setting
class TemplateItems(BaseSetting):
page_banner = models.OneToOneField('wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+', help_text='Banner image that shows below menu on pages other than home page')
footer_link_col1_header = models.CharField(max_length=25, default='', verbose_name='Footer Link Column 1 Header')
footer_link_col2_header = models.CharField(max_length=25, blank=True, default='', verbose_name='Footer Link Column 2 Header')
footer_link_col3_header = models.CharField(max_length=25, blank=True, default='', verbose_name='Footer Link Column 3 Header')
footer_link_col4_header = models.CharField(max_length=25, blank=True, default='', verbose_name='Footer Link Column 4 Header')
panels = [
ImageChooserPanel('page_banner'),
MultiFieldPanel([
FieldPanel('footer_link_col1_header'),
InlinePanel('footer_links_col_1', label='Column 1 Links'),
FieldPanel('footer_link_col2_header'),
InlinePanel('footer_links_col_2', label='Column 2 Links'),
FieldPanel('footer_link_col3_header'),
InlinePanel('footer_links_col_3', label='Column 3 Links'),
FieldPanel('footer_link_col4_header'),
InlinePanel('footer_links_col_4', label='Column 4 Links'),
], heading='Footer Links'),
InlinePanel('social_media_links', label="Social Media Links"),
]
class FooterLink(Orderable):
name = models.CharField(max_length=60, default='')
url = models.CharField(max_length=200, default='')
panels = [
FieldRowPanel([
FieldPanel('name'),
FieldPanel('url'),
])
]
class Meta:
abstract = True
def __str__(self):
return f'{self.name}'
class FooterLinkCol1(FooterLink):
template_items = ForeignKey('TemplateItems', related_name='footer_links_col_1', null=True, on_delete=models.SET_NULL)
class FooterLinkCol2(FooterLink):
template_items = ForeignKey('TemplateItems', related_name='footer_links_col_2', null=True, on_delete=models.SET_NULL)
class FooterLinkCol3(FooterLink):
template_items = ForeignKey('TemplateItems', related_name='footer_links_col_3', null=True, on_delete=models.SET_NULL)
class FooterLinkCol4(FooterLink):
template_items = ForeignKey('TemplateItems', related_name='footer_links_col_4', null=True, on_delete=models.SET_NULL)
迁移已成功创建和迁移,但是当我转到 Wagtail 管理中的 TemplateItems
设置对象以添加页脚 links 时,我收到以下错误:
KeyError at /admin/settings/main/templateitems/2/
'footer_links_col_1'
如果我注释掉任何 footer_links_col_X 项,那么我会收到第一个未注释掉的错误。数据库中没有任何列的现有页脚 link。我想知道问题是不是因为 ForeignKey
是 BaseSetting
对象,但是当我在 Django 管理中声明这些模型时(包括每个列的内联 links) ,它显示并允许我添加 links 就好了。
回溯:
File
"/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/django/core/handlers/exception.py"
in inner
34. response = get_response(request)
File
"/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/django/core/handlers/base.py"
in _get_response
126. response = self.process_exception_by_middleware(e, request)
File
"/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/django/core/handlers/base.py"
in _get_response
124. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File
"/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/django/views/decorators/cache.py"
in _wrapped_view_func
44. response = view_func(request, *args, **kwargs)
File
"/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/wagtail/admin/urls/init.py"
in wrapper
102. return view_func(request, *args, **kwargs)
File
"/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/wagtail/admin/decorators.py"
in decorated_view
34. return view_func(request, *args, **kwargs)
File
"/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/wagtail/contrib/settings/views.py"
in edit
83. instance=instance, form=form, request=request)
File
"/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/wagtail/admin/edit_handlers.py"
in bind_to_instance
153. new.on_instance_bound()
File
"/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/wagtail/admin/edit_handlers.py"
in on_instance_bound
295. request=self.request))
File
"/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/wagtail/admin/edit_handlers.py"
in bind_to_instance
153. new.on_instance_bound()
File
"/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/wagtail/admin/edit_handlers.py"
in on_instance_bound
295. request=self.request))
File
"/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/wagtail/admin/edit_handlers.py"
in bind_to_instance
153. new.on_instance_bound()
File
"/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/wagtail/admin/edit_handlers.py"
in on_instance_bound
692. self.formset = self.form.formsets[self.relation_name]
Exception Type: KeyError at /admin/settings/main/templateitems/2/
Exception Value: 'footer_links_col_1'
InlinePanel要求对应的外键是ParentalKey
:
from modelcluster.fields import ParentalKey
class FooterLinkCol1(FooterLink):
template_items = ParentalKey('TemplateItems', related_name='footer_links_col_1', null=True, on_delete=models.SET_NULL)
反过来,ParentalKey 要求父模型继承自 ClusterableModel
(对于 Wagtail Page
模型自动成立):
from modelcluster.models import ClusterableModel
class TemplateItems(BaseSetting, ClusterableModel):
(在 the readme for django-modelcluster 中对 ClusterableModel / ParentalKey 的动机做了一些解释。)
Django 版本:2.1.5
Python版本:3.6.8
鹡鸰版本: 2.4
我有一个模板,其页脚中有四列 link。我已经为 link 的每一列设置了以下模型,其中包含一个 BaseSetting
对象和页脚 link 对象。页脚 link 对象每个 ForeignKey
到 TemplateItems
对象。
@register_setting
class TemplateItems(BaseSetting):
page_banner = models.OneToOneField('wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+', help_text='Banner image that shows below menu on pages other than home page')
footer_link_col1_header = models.CharField(max_length=25, default='', verbose_name='Footer Link Column 1 Header')
footer_link_col2_header = models.CharField(max_length=25, blank=True, default='', verbose_name='Footer Link Column 2 Header')
footer_link_col3_header = models.CharField(max_length=25, blank=True, default='', verbose_name='Footer Link Column 3 Header')
footer_link_col4_header = models.CharField(max_length=25, blank=True, default='', verbose_name='Footer Link Column 4 Header')
panels = [
ImageChooserPanel('page_banner'),
MultiFieldPanel([
FieldPanel('footer_link_col1_header'),
InlinePanel('footer_links_col_1', label='Column 1 Links'),
FieldPanel('footer_link_col2_header'),
InlinePanel('footer_links_col_2', label='Column 2 Links'),
FieldPanel('footer_link_col3_header'),
InlinePanel('footer_links_col_3', label='Column 3 Links'),
FieldPanel('footer_link_col4_header'),
InlinePanel('footer_links_col_4', label='Column 4 Links'),
], heading='Footer Links'),
InlinePanel('social_media_links', label="Social Media Links"),
]
class FooterLink(Orderable):
name = models.CharField(max_length=60, default='')
url = models.CharField(max_length=200, default='')
panels = [
FieldRowPanel([
FieldPanel('name'),
FieldPanel('url'),
])
]
class Meta:
abstract = True
def __str__(self):
return f'{self.name}'
class FooterLinkCol1(FooterLink):
template_items = ForeignKey('TemplateItems', related_name='footer_links_col_1', null=True, on_delete=models.SET_NULL)
class FooterLinkCol2(FooterLink):
template_items = ForeignKey('TemplateItems', related_name='footer_links_col_2', null=True, on_delete=models.SET_NULL)
class FooterLinkCol3(FooterLink):
template_items = ForeignKey('TemplateItems', related_name='footer_links_col_3', null=True, on_delete=models.SET_NULL)
class FooterLinkCol4(FooterLink):
template_items = ForeignKey('TemplateItems', related_name='footer_links_col_4', null=True, on_delete=models.SET_NULL)
迁移已成功创建和迁移,但是当我转到 Wagtail 管理中的 TemplateItems
设置对象以添加页脚 links 时,我收到以下错误:
KeyError at /admin/settings/main/templateitems/2/
'footer_links_col_1'
如果我注释掉任何 footer_links_col_X 项,那么我会收到第一个未注释掉的错误。数据库中没有任何列的现有页脚 link。我想知道问题是不是因为 ForeignKey
是 BaseSetting
对象,但是当我在 Django 管理中声明这些模型时(包括每个列的内联 links) ,它显示并允许我添加 links 就好了。
回溯:
File "/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner 34. response = get_response(request)
File "/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response 126. response = self.process_exception_by_middleware(e, request)
File "/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response 124. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/django/views/decorators/cache.py" in _wrapped_view_func 44. response = view_func(request, *args, **kwargs)
File "/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/wagtail/admin/urls/init.py" in wrapper 102. return view_func(request, *args, **kwargs)
File "/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/wagtail/admin/decorators.py" in decorated_view 34. return view_func(request, *args, **kwargs)
File "/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/wagtail/contrib/settings/views.py" in edit 83. instance=instance, form=form, request=request)
File "/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/wagtail/admin/edit_handlers.py" in bind_to_instance 153. new.on_instance_bound()
File "/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/wagtail/admin/edit_handlers.py" in on_instance_bound 295. request=self.request))
File "/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/wagtail/admin/edit_handlers.py" in bind_to_instance 153. new.on_instance_bound()
File "/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/wagtail/admin/edit_handlers.py" in on_instance_bound 295. request=self.request))
File "/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/wagtail/admin/edit_handlers.py" in bind_to_instance 153. new.on_instance_bound()
File "/opt/virtualenvs/MY_SITE-a0hNfZxl/lib/python3.6/site-packages/wagtail/admin/edit_handlers.py" in on_instance_bound 692. self.formset = self.form.formsets[self.relation_name]
Exception Type: KeyError at /admin/settings/main/templateitems/2/ Exception Value: 'footer_links_col_1'
InlinePanel要求对应的外键是ParentalKey
:
from modelcluster.fields import ParentalKey
class FooterLinkCol1(FooterLink):
template_items = ParentalKey('TemplateItems', related_name='footer_links_col_1', null=True, on_delete=models.SET_NULL)
反过来,ParentalKey 要求父模型继承自 ClusterableModel
(对于 Wagtail Page
模型自动成立):
from modelcluster.models import ClusterableModel
class TemplateItems(BaseSetting, ClusterableModel):
(在 the readme for django-modelcluster 中对 ClusterableModel / ParentalKey 的动机做了一些解释。)