Set TreeQueryset.delete.queryset_only = True (#5938)

Fixes wagtail/wagtail#5937

This reverts Wagtail's behaviour to match Django's, where an error is
raised as a safety mechanism.

Projects relying on the non-safe behaviour should update e.g.
`MyModel.objects.delete()` to `MyModel.objects.all().delete()`.
pull/5965/head
Nick Smith 2020-04-07 10:20:23 +01:00 zatwierdzone przez Matt Westcott
rodzic 0017216a02
commit 555adccc2a
4 zmienionych plików z 22 dodań i 0 usunięć

Wyświetl plik

@ -43,6 +43,7 @@ Changelog
* Fix: Hide empty 'view live' links (Karran Besen)
* Fix: Mark up a few strings for translation (Luiz Boaretto)
* Fix: Invalid focal_point attribute on image edit view (Michał (Quadric) Sieradzki)
* Fix: No longer expose the `.delete()` method on the default Page.objects manager (Nick Smith)
2.8.1 (14.04.2020)

Wyświetl plik

@ -61,6 +61,7 @@ Bug fixes
* Hide empty 'view live' links (Karran Besen)
* Mark up a few strings for translation (Luiz Boaretto)
* Invalid focal_point attribute on image edit view (Michał (Quadric) Sieradzki)
* No longer expose the ``.delete()`` method on the default Page.objects manager (Nick Smith)
Upgrade considerations
@ -76,3 +77,9 @@ Django 2.1 is no longer supported as of this release; please upgrade to Django 2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Wagtail's :class:`~wagtail.core.middleware.SiteMiddleware`, which makes the current site object available as the property ``request.site``, is now deprecated as it clashes with Django's sites framework and makes unnecessary database queries on non-Wagtail views. References to ``request.site`` in your code should be removed; the recommended way of retrieving the current site is ``Site.find_for_request(request)`` in Python code, and the ``{% wagtail_site %}`` tag within Django templates. Once these are removed, ``'wagtail.core.middleware.SiteMiddleware'`` can be removed from your project's ``MIDDLEWARE`` setting.
Page / Collection managers no longer expose a ``delete`` method
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For `consistency with standard Django models <https://docs.djangoproject.com/en/stable/topics/db/queries/#deleting-objects>`_, the ``delete()`` method is no longer available on the default Page and Collection managers. Code such as ``Page.objects.delete()`` should be changed to ``Page.objects.all().delete()``.

Wyświetl plik

@ -15,6 +15,12 @@ class TreeQuerySet(MP_NodeQuerySet):
"""
Extends Treebeard's MP_NodeQuerySet with additional useful tree-related operations.
"""
def delete(self):
"""Redefine the delete method unbound, so we can set the queryset_only parameter. """
super().delete()
delete.queryset_only = True
def descendant_of_q(self, other, inclusive=False):
q = Q(path__startswith=other.path) & Q(depth__gte=other.depth)

Wyświetl plik

@ -406,6 +406,14 @@ class TestPageQuerySet(TestCase):
self.assertTrue(Page.objects.filter(query).exists())
def test_delete_queryset(self):
Page.objects.all().delete()
self.assertEqual(Page.objects.count(), 0)
def test_delete_is_not_available_on_manager(self):
with self.assertRaises(AttributeError):
Page.objects.delete()
class TestPageQueryInSite(TestCase):
fixtures = ['test.json']