diff --git a/AUTHORS b/AUTHORS index e9eff0f6a6..ca2960f17d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -107,6 +107,7 @@ answer newbie questions, and generally made Django that much better: Brian Ray Brian Rosner Bruce Kroeze + Bruno Alla Bruno ReniƩ brut.alll@gmail.com Bryan Chow diff --git a/tests/basic/tests.py b/tests/basic/tests.py index 3dc3c3ba56..9ea0695e25 100644 --- a/tests/basic/tests.py +++ b/tests/basic/tests.py @@ -178,150 +178,6 @@ class ModelTest(TestCase): self.assertTrue(Article.objects.get(id__exact=a1.id) != Article.objects.get(id__exact=a2.id)) self.assertFalse(Article.objects.get(id__exact=a2.id) == Article.objects.get(id__exact=a1.id)) - def test_lookup(self): - # No articles are in the system yet. - self.assertQuerysetEqual(Article.objects.all(), []) - - # Create an Article. - a = Article( - id=None, - headline='Area man programs in Python', - pub_date=datetime(2005, 7, 28), - ) - - # Save it into the database. You have to call save() explicitly. - a.save() - - # Now it has an ID. - self.assertTrue(a.id is not None) - - # Models have a pk property that is an alias for the primary key - # attribute (by default, the 'id' attribute). - self.assertEqual(a.pk, a.id) - - # Access database columns via Python attributes. - self.assertEqual(a.headline, 'Area man programs in Python') - self.assertEqual(a.pub_date, datetime(2005, 7, 28, 0, 0)) - - # Change values by changing the attributes, then calling save(). - a.headline = 'Area woman programs in Python' - a.save() - - # Article.objects.all() returns all the articles in the database. - self.assertQuerysetEqual(Article.objects.all(), - ['']) - - # Django provides a rich database lookup API. - self.assertEqual(Article.objects.get(id__exact=a.id), a) - self.assertEqual(Article.objects.get(headline__startswith='Area woman'), a) - self.assertEqual(Article.objects.get(pub_date__year=2005), a) - self.assertEqual(Article.objects.get(pub_date__year=2005, pub_date__month=7), a) - self.assertEqual(Article.objects.get(pub_date__year=2005, pub_date__month=7, pub_date__day=28), a) - self.assertEqual(Article.objects.get(pub_date__week_day=5), a) - - # The "__exact" lookup type can be omitted, as a shortcut. - self.assertEqual(Article.objects.get(id=a.id), a) - self.assertEqual(Article.objects.get(headline='Area woman programs in Python'), a) - - self.assertQuerysetEqual( - Article.objects.filter(pub_date__year=2005), - [''], - ) - self.assertQuerysetEqual( - Article.objects.filter(pub_date__year=2004), - [], - ) - self.assertQuerysetEqual( - Article.objects.filter(pub_date__year=2005, pub_date__month=7), - [''], - ) - - self.assertQuerysetEqual( - Article.objects.filter(pub_date__week_day=5), - [''], - ) - self.assertQuerysetEqual( - Article.objects.filter(pub_date__week_day=6), - [], - ) - - # Django raises an Article.DoesNotExist exception for get() if the - # parameters don't match any object. - six.assertRaisesRegex( - self, - ObjectDoesNotExist, - "Article matching query does not exist.", - Article.objects.get, - id__exact=2000, - ) - # To avoid dict-ordering related errors check only one lookup - # in single assert. - self.assertRaises( - ObjectDoesNotExist, - Article.objects.get, - pub_date__year=2005, - pub_date__month=8, - ) - - six.assertRaisesRegex( - self, - ObjectDoesNotExist, - "Article matching query does not exist.", - Article.objects.get, - pub_date__week_day=6, - ) - - # Lookup by a primary key is the most common case, so Django - # provides a shortcut for primary-key exact lookups. - # The following is identical to articles.get(id=a.id). - self.assertEqual(Article.objects.get(pk=a.id), a) - - # pk can be used as a shortcut for the primary key name in any query. - self.assertQuerysetEqual(Article.objects.filter(pk__in=[a.id]), - [""]) - - # Model instances of the same type and same ID are considered equal. - a = Article.objects.get(pk=a.id) - b = Article.objects.get(pk=a.id) - self.assertEqual(a, b) - - # Create a very similar object - a = Article( - id=None, - headline='Area man programs in Python', - pub_date=datetime(2005, 7, 28), - ) - a.save() - - self.assertEqual(Article.objects.count(), 2) - - # Django raises an Article.MultipleObjectsReturned exception if the - # lookup matches more than one object - six.assertRaisesRegex( - self, - MultipleObjectsReturned, - "get\(\) returned more than one Article -- it returned 2!", - Article.objects.get, - headline__startswith='Area', - ) - - six.assertRaisesRegex( - self, - MultipleObjectsReturned, - "get\(\) returned more than one Article -- it returned 2!", - Article.objects.get, - pub_date__year=2005, - ) - - six.assertRaisesRegex( - self, - MultipleObjectsReturned, - "get\(\) returned more than one Article -- it returned 2!", - Article.objects.get, - pub_date__year=2005, - pub_date__month=7, - ) - def test_multiple_objects_max_num_fetched(self): """ #6785 - get() should fetch a limited number of results. @@ -584,6 +440,140 @@ class ModelTest(TestCase): hash(Article()) +class ModelLookupTest(TestCase): + def setUp(self): + # Create an Article. + self.a = Article( + id=None, + headline='Area woman programs in Python', + pub_date=datetime(2005, 7, 28), + ) + # Save it into the database. You have to call save() explicitly. + self.a.save() + + def test_all_lookup(self): + # Change values by changing the attributes, then calling save(). + self.a.headline = 'Area man programs in Python' + self.a.save() + + # Article.objects.all() returns all the articles in the database. + self.assertQuerysetEqual(Article.objects.all(), + ['']) + + def test_rich_lookup(self): + # Django provides a rich database lookup API. + self.assertEqual(Article.objects.get(id__exact=self.a.id), self.a) + self.assertEqual(Article.objects.get(headline__startswith='Area woman'), self.a) + self.assertEqual(Article.objects.get(pub_date__year=2005), self.a) + self.assertEqual(Article.objects.get(pub_date__year=2005, pub_date__month=7), self.a) + self.assertEqual(Article.objects.get(pub_date__year=2005, pub_date__month=7, pub_date__day=28), self.a) + self.assertEqual(Article.objects.get(pub_date__week_day=5), self.a) + + def test_equal_lookup(self): + # The "__exact" lookup type can be omitted, as a shortcut. + self.assertEqual(Article.objects.get(id=self.a.id), self.a) + self.assertEqual(Article.objects.get(headline='Area woman programs in Python'), self.a) + + self.assertQuerysetEqual( + Article.objects.filter(pub_date__year=2005), + [''], + ) + self.assertQuerysetEqual( + Article.objects.filter(pub_date__year=2004), + [], + ) + self.assertQuerysetEqual( + Article.objects.filter(pub_date__year=2005, pub_date__month=7), + [''], + ) + + self.assertQuerysetEqual( + Article.objects.filter(pub_date__week_day=5), + [''], + ) + self.assertQuerysetEqual( + Article.objects.filter(pub_date__week_day=6), + [], + ) + + def test_does_not_exist(self): + # Django raises an Article.DoesNotExist exception for get() if the + # parameters don't match any object. + six.assertRaisesRegex( + self, + ObjectDoesNotExist, + "Article matching query does not exist.", + Article.objects.get, + id__exact=2000, + ) + # To avoid dict-ordering related errors check only one lookup + # in single assert. + self.assertRaises( + ObjectDoesNotExist, + Article.objects.get, + pub_date__year=2005, + pub_date__month=8, + ) + six.assertRaisesRegex( + self, + ObjectDoesNotExist, + "Article matching query does not exist.", + Article.objects.get, + pub_date__week_day=6, + ) + + def test_lookup_by_primary_key(self): + # Lookup by a primary key is the most common case, so Django + # provides a shortcut for primary-key exact lookups. + # The following is identical to articles.get(id=a.id). + self.assertEqual(Article.objects.get(pk=self.a.id), self.a) + + # pk can be used as a shortcut for the primary key name in any query. + self.assertQuerysetEqual(Article.objects.filter(pk__in=[self.a.id]), + [""]) + + # Model instances of the same type and same ID are considered equal. + a = Article.objects.get(pk=self.a.id) + b = Article.objects.get(pk=self.a.id) + self.assertEqual(a, b) + + def test_too_many(self): + # Create a very similar object + a = Article( + id=None, + headline='Area man programs in Python', + pub_date=datetime(2005, 7, 28), + ) + a.save() + + self.assertEqual(Article.objects.count(), 2) + + # Django raises an Article.MultipleObjectsReturned exception if the + # lookup matches more than one object + six.assertRaisesRegex( + self, + MultipleObjectsReturned, + "get\(\) returned more than one Article -- it returned 2!", + Article.objects.get, + headline__startswith='Area', + ) + six.assertRaisesRegex( + self, + MultipleObjectsReturned, + "get\(\) returned more than one Article -- it returned 2!", + Article.objects.get, + pub_date__year=2005, + ) + six.assertRaisesRegex( + self, + MultipleObjectsReturned, + "get\(\) returned more than one Article -- it returned 2!", + Article.objects.get, + pub_date__year=2005, + pub_date__month=7, + ) + + class ConcurrentSaveTests(TransactionTestCase): available_apps = ['basic']