mirror of
https://github.com/wagtail/wagtail.git
synced 2024-12-01 11:41:20 +01:00
Prevent exception when attempting to delete a model with a protected 1-to-1 relation
Modeladmin handles notification to the user if a model instance has protected ForeignKey relationships. However, if the protected relation is a OneToOneField it raises an exception: File ".../wagtail/wagtail/contrib/modeladmin/views.py", line 742, in post for obj in qs.all(): AttributeError: 'MyRelatedModel' object has no attribute 'all' because qs in this case is the related instance rather than a queryset of related instances (as is the case for a ForeignKey). This commit handles the OneToOneField case as well.
This commit is contained in:
parent
cdb13b6490
commit
4a93424654
@ -10,6 +10,7 @@ Changelog
|
||||
* Fix: Added https support for Scribd oEmbed provider (Rodrigo)
|
||||
* Fix: Changed StreamField group labels color so labels are visible (Catherine Farman)
|
||||
* Fix: Prevented images with a very wide aspect ratio from being displayed distorted in the rich text editor (Iman Syed)
|
||||
* Fix: Prevent exception when deleting a model with a protected One-to-one relationship (Neal Todd)
|
||||
|
||||
|
||||
2.6.1 (xx.xx.xxxx) - IN DEVELOPMENT
|
||||
|
@ -28,6 +28,7 @@ Bug fixes
|
||||
* Added https support for Scribd oEmbed provider (Rodrigo)
|
||||
* Changed StreamField group label color so labels are visible (Catherine Farman)
|
||||
* Prevented images with a very wide aspect ratio from being displayed distorted in the rich text editor (Iman Syed)
|
||||
* Prevent exception when deleting a model with a protected One-to-one relationship (Neal Todd)
|
||||
|
||||
|
||||
Upgrade considerations
|
||||
|
@ -439,6 +439,23 @@ class TestDeleteViewWithProtectedRelation(TestCase, WagtailTestUtils):
|
||||
self.assertFalse(Author.objects.filter(id=4).exists())
|
||||
|
||||
|
||||
def test_post_with_1to1_dependent_object(self):
|
||||
response = self.post(5)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(
|
||||
response,
|
||||
"'Harper Lee' is currently referenced by other objects"
|
||||
)
|
||||
self.assertContains(
|
||||
response,
|
||||
"<li><b>Solo Book:</b> To Kill a Mockingbird</li>"
|
||||
)
|
||||
|
||||
# Author not deleted
|
||||
self.assertTrue(Author.objects.filter(id=5).exists())
|
||||
|
||||
|
||||
class TestDeleteViewModelReprPrimary(TestCase, WagtailTestUtils):
|
||||
fixtures = ['modeladmintest_test.json']
|
||||
|
||||
|
@ -6,11 +6,12 @@ from django.contrib.admin.options import IncorrectLookupParameters
|
||||
from django.contrib.admin.utils import (
|
||||
get_fields_from_path, label_for_field, lookup_needs_distinct, prepare_lookup_value, quote, unquote)
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.core.exceptions import ImproperlyConfigured, PermissionDenied, SuspiciousOperation
|
||||
from django.core.exceptions import (
|
||||
ImproperlyConfigured, ObjectDoesNotExist, PermissionDenied, SuspiciousOperation)
|
||||
from django.core.paginator import InvalidPage, Paginator
|
||||
from django.db import models
|
||||
from django.db.models.fields import FieldDoesNotExist
|
||||
from django.db.models.fields.related import ManyToManyField
|
||||
from django.db.models.fields.related import ManyToManyField, OneToOneRel
|
||||
from django.shortcuts import get_object_or_404, redirect
|
||||
from django.template.defaultfilters import filesizeformat
|
||||
from django.utils.decorators import method_decorator
|
||||
@ -738,9 +739,17 @@ class DeleteView(InstanceSpecificView):
|
||||
obj.field, ManyToManyField))
|
||||
for rel in fields:
|
||||
if rel.on_delete == models.PROTECT:
|
||||
qs = getattr(self.instance, rel.get_accessor_name())
|
||||
for obj in qs.all():
|
||||
linked_objects.append(obj)
|
||||
if isinstance(rel, OneToOneRel):
|
||||
try:
|
||||
obj = getattr(self.instance, rel.get_accessor_name())
|
||||
except ObjectDoesNotExist:
|
||||
pass
|
||||
else:
|
||||
linked_objects.append(obj)
|
||||
else:
|
||||
qs = getattr(self.instance, rel.get_accessor_name())
|
||||
for obj in qs.all():
|
||||
linked_objects.append(obj)
|
||||
context = self.get_context_data(
|
||||
protected_error=True,
|
||||
linked_objects=linked_objects
|
||||
|
@ -31,6 +31,14 @@
|
||||
"date_of_birth": "1898-11-29"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 5,
|
||||
"model": "modeladmintest.author",
|
||||
"fields": {
|
||||
"name": "Harper Lee",
|
||||
"date_of_birth": "1926-04-28"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 1,
|
||||
"model": "modeladmintest.book",
|
||||
@ -63,6 +71,14 @@
|
||||
"author_id": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 4,
|
||||
"model": "modeladmintest.solobook",
|
||||
"fields": {
|
||||
"title": "To Kill a Mockingbird",
|
||||
"author_id": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": "boom",
|
||||
"model": "modeladmintest.token",
|
||||
|
22
wagtail/tests/modeladmintest/migrations/0008_solobook.py
Normal file
22
wagtail/tests/modeladmintest/migrations/0008_solobook.py
Normal file
@ -0,0 +1,22 @@
|
||||
# Generated by Django 2.1.10 on 2019-07-17 17:46
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('modeladmintest', '0007_friend'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='SoloBook',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('title', models.CharField(max_length=255)),
|
||||
('author', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='modeladmintest.Author')),
|
||||
],
|
||||
),
|
||||
]
|
@ -40,6 +40,14 @@ class Book(models.Model, index.Indexed):
|
||||
return self.title
|
||||
|
||||
|
||||
class SoloBook(models.Model):
|
||||
author = models.OneToOneField(Author, on_delete=models.PROTECT)
|
||||
title = models.CharField(max_length=255)
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
|
||||
class Token(models.Model):
|
||||
key = models.CharField(max_length=40, primary_key=True)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user