-
Notifications
You must be signed in to change notification settings - Fork 13
Open
Labels
type:BugSomething isn't workingSomething isn't working
Description
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="+".
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",
- 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:
- I have confirmed that this issue can be reproduced as described on a fresh Wagtail project: no
Technical details
- Python version: 3.6
- Django version: 2.2.17
- Wagtail version: 2.11.3
- Browser version: Edge 87
Metadata
Metadata
Assignees
Labels
type:BugSomething isn't workingSomething isn't working