This is a bug related to wagtail/wagtail#5437, which added exception handling for deletion of objects that throw a ProtectedError.
I observed that the existing code does not work if the ForeignKey/OneToOneField relationship uses related_name="+".
AttributeError at /admin/videos/video/delete/18/
'Video' object has no attribute '+'
...
Exception Location: /wagtail/contrib/modeladmin/views.py in post, line 814
The code at line 814 is qs = getattr(self.instance, rel.get_accessor_name()), and it makes sense that the code fails when rel.get_accessor_name() == "+".
Steps to Reproduce
Start a new project with wagtail start myproject
Create a videos app with a Video model (code sample below)
Create a VideoPage model (code sample below)
Register the model admin (code sample below)
Create a couple sample videos and video pages
Select a video in the admin interface that is associated with a page, and delete the video
Confirm the AttributeError occurs
# models.py
class Video(models.Model):
title = models.CharField(max_length=255)
panels = [
FieldPanel("title"),
]
class VideoPage(Page):
video = models.ForeignKey(
"videos.Video",
on_delete=models.PROTECT,
related_name="+",
)
content_panels = Page.content_panels + [
FieldPanel("video", widget=VideoChooser),
]
# wagtail_hooks.py
from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register
class VideoModelAdmin(ModelAdmin):
@cached_property
def model(self):
from videos.models import Video
return Video
modeladmin_register(VideoModelAdmin)
Any other relevant information. For example, why do you consider this a bug and what did you expect to happen instead?
The workarounds for this scenario I'm aware of are:
Don't use PROTECT
Don't use related_name="+"
This is appealing, but becomes a nuisance when using inheritance, because the related_name needs to be unique. The solution I found was to inject the class name into the related_name: related_name="%(app_label)s_%(class)s_related_pages",
I have confirmed that this issue can be reproduced as described on a fresh Wagtail project: no
Issue Summary
This is a bug related to wagtail/wagtail#5437, which added exception handling for deletion of objects that throw a ProtectedError.
I observed that the existing code does not work if the ForeignKey/OneToOneField relationship uses related_name="+".
The code at line 814 is
qs = getattr(self.instance, rel.get_accessor_name())
, and it makes sense that the code fails whenrel.get_accessor_name() == "+"
.Steps to Reproduce
wagtail start myproject
Any other relevant information. For example, why do you consider this a bug and what did you expect to happen instead?
The workarounds for this scenario I'm aware of are:
related_name="%(app_label)s_%(class)s_related_pages",
Technical details