From 73ee469f0b54c8434172cb56d4e232818af6b76f Mon Sep 17 00:00:00 2001 From: Matthias Kestenholz Date: Sun, 18 Aug 2024 10:57:12 +0200 Subject: [PATCH] Test the behavior of .descendants() queries --- CHANGELOG.rst | 4 ++- tests/testapp/test_queries.py | 49 +++++++++++++++++++++++++++++++++++ tox.ini | 2 +- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c6d15fc..acca5cc 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,7 +4,9 @@ Change log Next version ~~~~~~~~~~~~ -- Added Django 5.1b1 to the testsuite. +- Added Django 5.1 to the testsuite. +- Added tests showing that ``.descendants().update(...)`` doesn't work, but + ``.filter(pk__in=....descendants()).update(...)`` does. 0.19 (2024-04-25) diff --git a/tests/testapp/test_queries.py b/tests/testapp/test_queries.py index 1627456..90b6e93 100644 --- a/tests/testapp/test_queries.py +++ b/tests/testapp/test_queries.py @@ -5,6 +5,7 @@ from django.db import connections, models from django.db.models import Count, Q, Sum from django.db.models.expressions import RawSQL +from django.db.utils import OperationalError from django.test import TestCase, override_settings from testapp.models import ( @@ -159,6 +160,54 @@ def test_update_aggregate(self): # known yet. ) + def test_update_descendants(self): + """UpdateQuery does not work with tree queries""" + tree = self.create_tree() + with self.assertRaises(OperationalError) as cm: + tree.root.descendants().update(name="test") + self.assertIn("__tree.tree_path", str(cm.exception)) + + def test_update_descendants_with_filter(self): + """Updating works when using a filter""" + tree = self.create_tree() + Model.objects.filter(pk__in=tree.child2.descendants()).update(name="test") + self.assertEqual( + [node.name for node in Model.objects.with_tree_fields()], + [ + "root", + "1", + "1-1", + "2", + "test", + "test", + ], + ) + + def test_delete_descendants(self): + """DeleteQuery works with tree queries""" + tree = self.create_tree() + tree.child2.descendants(include_self=True).delete() + + self.assertEqual( + list(Model.objects.with_tree_fields()), + [ + tree.root, + tree.child1, + tree.child1_1, + # tree.child2, + # tree.child2_1, + # tree.child2_2, + ], + ) + + def test_aggregate_descendants(self): + """AggregateQuery works with tree queries""" + tree = self.create_tree() + self.assertEqual( + tree.root.descendants(include_self=True).aggregate(Sum("pk"))["pk__sum"], + sum(node.pk for node in Model.objects.all()), + ) + def test_values(self): self.create_tree() self.assertEqual( diff --git a/tox.ini b/tox.ini index 5f4e346..22aa149 100644 --- a/tox.ini +++ b/tox.ini @@ -10,7 +10,7 @@ deps = dj41: Django>=4.1,<4.2 dj42: Django>=4.2,<5.0 dj50: Django>=5.0,<5.1 - dj51: Django>=5.1b1,<5.2 + dj51: Django>=5.1,<5.2 djmain: https://github.com/django/django/archive/main.tar.gz postgresql: psycopg2-binary mysql: mysqlclient