如何在 Wagtail CMS 中为自定义图像模型自定义管理表单?
How to customize the admin form for a custom image model in Wagtail CMS?
我需要向 Wagtail 的 图像模型 添加一个 基于字符串的唯一 ID 。这些 ID 是字母、数字和标点符号的相对较短的组合,例如“AS.M-1.001”。因此,我使用带有 Django 标准 CharField
的 custom image model 和参数 unique=True
。但不幸的是,编辑表单不会检查 ID 是否唯一。所以我可以对多个图像使用相同的 ID。这种唯一性检查确实适用于 Wagtail 中的任何其他标准形式,例如Page
模型。但不适用于图像模型。
from django.db import models
from wagtail.images.models import Image, AbstractImage
class CustomImage(AbstractImage):
custom_id = models.CharField(max_length=32, unique=True, null=True, blank=True)
admin_form_fields = ( 'custom_id', ) + Image.admin_form_fields
我的方法是用自定义表单覆盖编辑表单以显示更多警告和错误,就像您可以对 Wagtail 的 Page
模型等使用 base_form_class
一样,as documented here. wagtail.admin.forms.WagtailAdminModelForm 和 wagtail.images.forms.BaseImageForm.
我都试过了
from wagtail.images.forms import BaseImageForm
from wagtail.admin.forms import WagtailAdminModelForm
class CustomImageForm(WagtailAdminModelForm):
# add more logic here
pass
class CustomImage(ArtButlerIDMixin, AbstractImage):
...
base_form_class = CustomImageForm
两者都导致相同的异常:
raise AppRegistryNotReady("Models aren't loaded yet.")
所以我尝试在我的设置中使用这些应用程序但没有效果。标准方法如何覆盖 Wagtail 中的管理表单是否完全适用于图像模型?还有什么其他方法可以让唯一的字符串标识符在这里工作? ... 或自定义此表单。
解决方案(更新)
按照@gasman 的建议,我将以下行添加到我的 settings/base.py
:
WAGTAILIMAGES_IMAGE_MODEL = 'images.CustomImage'
WAGTAILIMAGES_IMAGE_FORM_BASE = 'images.forms.CustomImageForm' # NEW
并在我的图片应用中向 forms.py
添加了以下表格:
from django.core.exceptions import ValidationError
from wagtail.images.forms import BaseImageForm
from .models import CustomImage
class CustomImageForm(BaseImageForm):
def clean(self):
cleaned_data = super().clean()
custom_id = cleaned_data.get("custom_id")
if CustomImage.objects.filter(custom_id=custom_id).exists():
raise ValidationError(
"Custom ID already exists"
)
return cleaned_data
Wagtail 中的图像不使用 WagtailAdminModelForm
或 base_form_class
属性 - 页面、代码片段和 ModelAdmin 使用这些属性来支持 Wagtail 特定的功能,例如内联子项和面板,但图像有效通过普通的 Django 模型和表单。
您可以通过子classing BaseImageForm 并在您的项目设置中设置WAGTAILIMAGES_IMAGE_FORM_BASE 来自定义表单。只要您在 models.py 之外的某处定义表单 class(例如,在单独的 forms.py 模块中),您将避免导致“未加载模型”的循环依赖还”错误。
我需要向 Wagtail 的 图像模型 添加一个 基于字符串的唯一 ID 。这些 ID 是字母、数字和标点符号的相对较短的组合,例如“AS.M-1.001”。因此,我使用带有 Django 标准 CharField
的 custom image model 和参数 unique=True
。但不幸的是,编辑表单不会检查 ID 是否唯一。所以我可以对多个图像使用相同的 ID。这种唯一性检查确实适用于 Wagtail 中的任何其他标准形式,例如Page
模型。但不适用于图像模型。
from django.db import models
from wagtail.images.models import Image, AbstractImage
class CustomImage(AbstractImage):
custom_id = models.CharField(max_length=32, unique=True, null=True, blank=True)
admin_form_fields = ( 'custom_id', ) + Image.admin_form_fields
我的方法是用自定义表单覆盖编辑表单以显示更多警告和错误,就像您可以对 Wagtail 的 Page
模型等使用 base_form_class
一样,as documented here. wagtail.admin.forms.WagtailAdminModelForm 和 wagtail.images.forms.BaseImageForm.
from wagtail.images.forms import BaseImageForm
from wagtail.admin.forms import WagtailAdminModelForm
class CustomImageForm(WagtailAdminModelForm):
# add more logic here
pass
class CustomImage(ArtButlerIDMixin, AbstractImage):
...
base_form_class = CustomImageForm
两者都导致相同的异常:
raise AppRegistryNotReady("Models aren't loaded yet.")
所以我尝试在我的设置中使用这些应用程序但没有效果。标准方法如何覆盖 Wagtail 中的管理表单是否完全适用于图像模型?还有什么其他方法可以让唯一的字符串标识符在这里工作? ... 或自定义此表单。
解决方案(更新)
按照@gasman 的建议,我将以下行添加到我的 settings/base.py
:
WAGTAILIMAGES_IMAGE_MODEL = 'images.CustomImage'
WAGTAILIMAGES_IMAGE_FORM_BASE = 'images.forms.CustomImageForm' # NEW
并在我的图片应用中向 forms.py
添加了以下表格:
from django.core.exceptions import ValidationError
from wagtail.images.forms import BaseImageForm
from .models import CustomImage
class CustomImageForm(BaseImageForm):
def clean(self):
cleaned_data = super().clean()
custom_id = cleaned_data.get("custom_id")
if CustomImage.objects.filter(custom_id=custom_id).exists():
raise ValidationError(
"Custom ID already exists"
)
return cleaned_data
Wagtail 中的图像不使用 WagtailAdminModelForm
或 base_form_class
属性 - 页面、代码片段和 ModelAdmin 使用这些属性来支持 Wagtail 特定的功能,例如内联子项和面板,但图像有效通过普通的 Django 模型和表单。
您可以通过子classing BaseImageForm 并在您的项目设置中设置WAGTAILIMAGES_IMAGE_FORM_BASE 来自定义表单。只要您在 models.py 之外的某处定义表单 class(例如,在单独的 forms.py 模块中),您将避免导致“未加载模型”的循环依赖还”错误。