Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

modeladmin PROTECTED with related_name="+" #30

Open
m3brown opened this issue Jan 19, 2021 · 0 comments
Open

modeladmin PROTECTED with related_name="+" #30

m3brown opened this issue Jan 19, 2021 · 0 comments
Labels
type:Bug Something isn't working

Comments

@m3brown
Copy link

m3brown commented Jan 19, 2021

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

  1. Start a new project with wagtail start myproject
  2. Create a videos app with a Video model (code sample below)
  3. Create a VideoPage model (code sample below)
  4. Register the model admin (code sample below)
  5. Create a couple sample videos and video pages
  6. Select a video in the admin interface that is associated with a page, and delete the video
  7. 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

Technical details

  • Python version: 3.6
  • Django version: 2.2.17
  • Wagtail version: 2.11.3
  • Browser version: Edge 87
@m3brown m3brown added the type:Bug Something isn't working label Jan 19, 2021
@laymonage laymonage transferred this issue from wagtail/wagtail Jul 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:Bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant