diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/modeltests/defer/tests.py | 20 | ||||
| -rw-r--r-- | tests/regressiontests/defer_regress/models.py | 4 | ||||
| -rw-r--r-- | tests/regressiontests/defer_regress/tests.py | 26 | ||||
| -rw-r--r-- | tests/regressiontests/select_related_regress/tests.py | 2 |
4 files changed, 44 insertions, 8 deletions
diff --git a/tests/modeltests/defer/tests.py b/tests/modeltests/defer/tests.py index eb09162b01..50db5a76b4 100644 --- a/tests/modeltests/defer/tests.py +++ b/tests/modeltests/defer/tests.py @@ -1,6 +1,6 @@ from __future__ import absolute_import -from django.db.models.query_utils import DeferredAttribute +from django.db.models.query_utils import DeferredAttribute, InvalidQuery from django.test import TestCase from .models import Secondary, Primary, Child, BigChild, ChildProxy @@ -73,9 +73,19 @@ class DeferTests(TestCase): self.assert_delayed(qs.defer("name").get(pk=p1.pk), 1) self.assert_delayed(qs.only("name").get(pk=p1.pk), 2) - # DOES THIS WORK? - self.assert_delayed(qs.only("name").select_related("related")[0], 1) - self.assert_delayed(qs.defer("related").select_related("related")[0], 0) + # When we defer a field and also select_related it, the query is + # invalid and raises an exception. + with self.assertRaises(InvalidQuery): + qs.only("name").select_related("related")[0] + with self.assertRaises(InvalidQuery): + qs.defer("related").select_related("related")[0] + + # With a depth-based select_related, all deferred ForeignKeys are + # deferred instead of traversed. + with self.assertNumQueries(3): + obj = qs.defer("related").select_related()[0] + self.assert_delayed(obj, 1) + self.assertEqual(obj.related.id, s1.pk) # Saving models with deferred fields is possible (but inefficient, # since every field has to be retrieved first). @@ -155,7 +165,7 @@ class DeferTests(TestCase): children = ChildProxy.objects.all().select_related().only('id', 'name') self.assertEqual(len(children), 1) child = children[0] - self.assert_delayed(child, 1) + self.assert_delayed(child, 2) self.assertEqual(child.name, 'p1') self.assertEqual(child.value, 'xx') diff --git a/tests/regressiontests/defer_regress/models.py b/tests/regressiontests/defer_regress/models.py index 812d2da206..bd4f845f27 100644 --- a/tests/regressiontests/defer_regress/models.py +++ b/tests/regressiontests/defer_regress/models.py @@ -47,3 +47,7 @@ class SimpleItem(models.Model): class Feature(models.Model): item = models.ForeignKey(SimpleItem) + +class ItemAndSimpleItem(models.Model): + item = models.ForeignKey(Item) + simple = models.ForeignKey(SimpleItem) diff --git a/tests/regressiontests/defer_regress/tests.py b/tests/regressiontests/defer_regress/tests.py index 1f07d4c9a8..53bb59f5b3 100644 --- a/tests/regressiontests/defer_regress/tests.py +++ b/tests/regressiontests/defer_regress/tests.py @@ -9,7 +9,7 @@ from django.db.models.loading import cache from django.test import TestCase from .models import (ResolveThis, Item, RelatedItem, Child, Leaf, Proxy, - SimpleItem, Feature) + SimpleItem, Feature, ItemAndSimpleItem) class DeferRegressionTest(TestCase): @@ -109,6 +109,7 @@ class DeferRegressionTest(TestCase): Child, Feature, Item, + ItemAndSimpleItem, Leaf, Proxy, RelatedItem, @@ -125,12 +126,16 @@ class DeferRegressionTest(TestCase): ), ) ) + # FIXME: This is dependent on the order in which tests are run -- + # this test case has to be the first, otherwise a LOT more classes + # appear. self.assertEqual( klasses, [ "Child", "Child_Deferred_value", "Feature", "Item", + "ItemAndSimpleItem", "Item_Deferred_name", "Item_Deferred_name_other_value_text", "Item_Deferred_name_other_value_value", @@ -139,7 +144,7 @@ class DeferRegressionTest(TestCase): "Leaf", "Leaf_Deferred_child_id_second_child_id_value", "Leaf_Deferred_name_value", - "Leaf_Deferred_second_child_value", + "Leaf_Deferred_second_child_id_value", "Leaf_Deferred_value", "Proxy", "RelatedItem", @@ -175,6 +180,23 @@ class DeferRegressionTest(TestCase): self.assertEqual(1, qs.count()) self.assertEqual('Foobar', qs[0].name) + def test_defer_with_select_related(self): + item1 = Item.objects.create(name="first", value=47) + item2 = Item.objects.create(name="second", value=42) + simple = SimpleItem.objects.create(name="simple", value="23") + related = ItemAndSimpleItem.objects.create(item=item1, simple=simple) + + obj = ItemAndSimpleItem.objects.defer('item').select_related('simple').get() + self.assertEqual(obj.item, item1) + self.assertEqual(obj.item_id, item1.id) + + obj.item = item2 + obj.save() + + obj = ItemAndSimpleItem.objects.defer('item').select_related('simple').get() + self.assertEqual(obj.item, item2) + self.assertEqual(obj.item_id, item2.id) + def test_deferred_class_factory(self): from django.db.models.query_utils import deferred_class_factory new_class = deferred_class_factory(Item, diff --git a/tests/regressiontests/select_related_regress/tests.py b/tests/regressiontests/select_related_regress/tests.py index e35157dbaf..73b0a8a875 100644 --- a/tests/regressiontests/select_related_regress/tests.py +++ b/tests/regressiontests/select_related_regress/tests.py @@ -133,7 +133,7 @@ class SelectRelatedRegressTests(TestCase): self.assertEqual(troy.state.name, 'Western Australia') # Also works if you use only, rather than defer - troy = SpecialClient.objects.select_related('state').only('name').get(name='Troy Buswell') + troy = SpecialClient.objects.select_related('state').only('name', 'state').get(name='Troy Buswell') self.assertEqual(troy.name, 'Troy Buswell') self.assertEqual(troy.value, 42) |
