summaryrefslogtreecommitdiff
path: root/tests/basic
diff options
context:
space:
mode:
authorAivars Kalvans <aivars.kalvans@gmail.com>2023-12-10 21:43:34 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2024-01-15 10:55:14 +0100
commitf92641a636a8cb75fc9851396cef4345510a4b52 (patch)
treeea37f35d62ca5807678c37de2292f8600ab22d6f /tests/basic
parentf3d10546a850df4fe3796f972d5b7e16adf52f54 (diff)
Fixed #28344 -- Allowed customizing queryset in Model.refresh_from_db()/arefresh_from_db().
The from_queryset parameter can be used to: - use a custom Manager - lock the row until the end of transaction - select additional related objects
Diffstat (limited to 'tests/basic')
-rw-r--r--tests/basic/tests.py56
1 files changed, 54 insertions, 2 deletions
diff --git a/tests/basic/tests.py b/tests/basic/tests.py
index 990549edfc..8a304e9ace 100644
--- a/tests/basic/tests.py
+++ b/tests/basic/tests.py
@@ -4,7 +4,14 @@ from datetime import datetime, timedelta
from unittest import mock
from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
-from django.db import DEFAULT_DB_ALIAS, DatabaseError, connections, models
+from django.db import (
+ DEFAULT_DB_ALIAS,
+ DatabaseError,
+ connection,
+ connections,
+ models,
+ transaction,
+)
from django.db.models.manager import BaseManager
from django.db.models.query import MAX_GET_RESULTS, EmptyQuerySet
from django.test import (
@@ -13,7 +20,8 @@ from django.test import (
TransactionTestCase,
skipUnlessDBFeature,
)
-from django.test.utils import ignore_warnings
+from django.test.utils import CaptureQueriesContext, ignore_warnings
+from django.utils.connection import ConnectionDoesNotExist
from django.utils.deprecation import RemovedInDjango60Warning
from django.utils.translation import gettext_lazy
@@ -1003,3 +1011,47 @@ class ModelRefreshTests(TestCase):
# Cache was cleared and new results are available.
self.assertCountEqual(a2_prefetched.selfref_set.all(), [s])
self.assertCountEqual(a2_prefetched.cited.all(), [s])
+
+ @skipUnlessDBFeature("has_select_for_update")
+ def test_refresh_for_update(self):
+ a = Article.objects.create(pub_date=datetime.now())
+ for_update_sql = connection.ops.for_update_sql()
+
+ with transaction.atomic(), CaptureQueriesContext(connection) as ctx:
+ a.refresh_from_db(from_queryset=Article.objects.select_for_update())
+ self.assertTrue(
+ any(for_update_sql in query["sql"] for query in ctx.captured_queries)
+ )
+
+ def test_refresh_with_related(self):
+ a = Article.objects.create(pub_date=datetime.now())
+ fa = FeaturedArticle.objects.create(article=a)
+
+ from_queryset = FeaturedArticle.objects.select_related("article")
+ with self.assertNumQueries(1):
+ fa.refresh_from_db(from_queryset=from_queryset)
+ self.assertEqual(fa.article.pub_date, a.pub_date)
+ with self.assertNumQueries(2):
+ fa.refresh_from_db()
+ self.assertEqual(fa.article.pub_date, a.pub_date)
+
+ def test_refresh_overwrites_queryset_using(self):
+ a = Article.objects.create(pub_date=datetime.now())
+
+ from_queryset = Article.objects.using("nonexistent")
+ with self.assertRaises(ConnectionDoesNotExist):
+ a.refresh_from_db(from_queryset=from_queryset)
+ a.refresh_from_db(using="default", from_queryset=from_queryset)
+
+ def test_refresh_overwrites_queryset_fields(self):
+ a = Article.objects.create(pub_date=datetime.now())
+ headline = "headline"
+ Article.objects.filter(pk=a.pk).update(headline=headline)
+
+ from_queryset = Article.objects.only("pub_date")
+ with self.assertNumQueries(1):
+ a.refresh_from_db(from_queryset=from_queryset)
+ self.assertNotEqual(a.headline, headline)
+ with self.assertNumQueries(1):
+ a.refresh_from_db(fields=["headline"], from_queryset=from_queryset)
+ self.assertEqual(a.headline, headline)