diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/modeltests/reserved_names/models.py | 2 | ||||
| -rw-r--r-- | tests/regressiontests/queries/models.py | 126 |
2 files changed, 116 insertions, 12 deletions
diff --git a/tests/modeltests/reserved_names/models.py b/tests/modeltests/reserved_names/models.py index a11b8d9f88..f698b5bc49 100644 --- a/tests/modeltests/reserved_names/models.py +++ b/tests/modeltests/reserved_names/models.py @@ -45,8 +45,6 @@ h b >>> print v.where 2005-01-01 ->>> Thing.objects.order_by('select.when') -[<Thing: a>, <Thing: h>] >>> Thing.objects.dates('where', 'year') [datetime.datetime(2005, 1, 1, 0, 0), datetime.datetime(2006, 1, 1, 0, 0)] diff --git a/tests/regressiontests/queries/models.py b/tests/regressiontests/queries/models.py index 64baacc32d..c775772ada 100644 --- a/tests/regressiontests/queries/models.py +++ b/tests/regressiontests/queries/models.py @@ -1,5 +1,5 @@ """ -Various combination queries that have been problematic in the past. +Various complex queries that have been problematic in the past. """ from django.db import models @@ -12,9 +12,29 @@ class Tag(models.Model): def __unicode__(self): return self.name +class Note(models.Model): + note = models.CharField(maxlength=100) + + class Meta: + ordering = ['note'] + + def __unicode__(self): + return self.note + +class ExtraInfo(models.Model): + info = models.CharField(maxlength=100) + note = models.ForeignKey(Note) + + class Meta: + ordering = ['info'] + + def __unicode__(self): + return self.info + class Author(models.Model): name = models.CharField(maxlength=10) num = models.IntegerField(unique=True) + extra = models.ForeignKey(ExtraInfo) def __unicode__(self): return self.name @@ -23,6 +43,10 @@ class Item(models.Model): name = models.CharField(maxlength=10) tags = models.ManyToManyField(Tag, blank=True, null=True) creator = models.ForeignKey(Author) + note = models.ForeignKey(Note) + + class Meta: + ordering = ['-note', 'name'] def __unicode__(self): return self.name @@ -34,6 +58,26 @@ class Report(models.Model): def __unicode__(self): return self.name +class Ranking(models.Model): + rank = models.IntegerField() + author = models.ForeignKey(Author) + + class Meta: + # A complex ordering specification. Should stress the system a bit. + ordering = ('author__extra__note', 'author__name', 'rank') + + def __unicode__(self): + return '%d: %s' % (self.rank, self.author.name) + +class Cover(models.Model): + title = models.CharField(maxlength=50) + item = models.ForeignKey(Item) + + class Meta: + ordering = ['item'] + + def __unicode__(self): + return self.title __test__ = {'API_TESTS':""" >>> t1 = Tag(name='t1') @@ -47,25 +91,38 @@ __test__ = {'API_TESTS':""" >>> t5 = Tag(name='t5', parent=t3) >>> t5.save() +>>> n1 = Note(note='n1') +>>> n1.save() +>>> n2 = Note(note='n2') +>>> n2.save() +>>> n3 = Note(note='n3') +>>> n3.save() ->>> a1 = Author(name='a1', num=1001) +Create these out of order so that sorting by 'id' will be different to sorting +by 'info'. Helps detect some problems later. +>>> e2 = ExtraInfo(info='e2', note=n2) +>>> e2.save() +>>> e1 = ExtraInfo(info='e1', note=n1) +>>> e1.save() + +>>> a1 = Author(name='a1', num=1001, extra=e1) >>> a1.save() ->>> a2 = Author(name='a2', num=2002) +>>> a2 = Author(name='a2', num=2002, extra=e1) >>> a2.save() ->>> a3 = Author(name='a3', num=3003) +>>> a3 = Author(name='a3', num=3003, extra=e2) >>> a3.save() ->>> a4 = Author(name='a4', num=4004) +>>> a4 = Author(name='a4', num=4004, extra=e2) >>> a4.save() ->>> i1 = Item(name='one', creator=a1) +>>> i1 = Item(name='one', creator=a1, note=n3) >>> i1.save() >>> i1.tags = [t1, t2] ->>> i2 = Item(name='two', creator=a2) +>>> i2 = Item(name='two', creator=a2, note=n2) >>> i2.save() >>> i2.tags = [t1, t3] ->>> i3 = Item(name='three', creator=a2) +>>> i3 = Item(name='three', creator=a2, note=n3) >>> i3.save() ->>> i4 = Item(name='four', creator=a4) +>>> i4 = Item(name='four', creator=a4, note=n3) >>> i4.save() >>> i4.tags = [t4] @@ -74,6 +131,20 @@ __test__ = {'API_TESTS':""" >>> r2 = Report(name='r2', creator=a3) >>> r2.save() +Ordering by 'rank' gives us rank2, rank1, rank3. Ordering by the Meta.ordering +will be rank3, rank2, rank1. +>>> rank1 = Ranking(rank=2, author=a2) +>>> rank1.save() +>>> rank2 = Ranking(rank=1, author=a3) +>>> rank2.save() +>>> rank3 = Ranking(rank=3, author=a1) +>>> rank3.save() + +>>> c1 = Cover(title="first", item=i4) +>>> c1.save() +>>> c2 = Cover(title="second", item=i2) +>>> c2.save() + Bug #1050 >>> Item.objects.filter(tags__isnull=True) [<Item: three>] @@ -119,7 +190,7 @@ Bug #1878, #2939 # Create something with a duplicate 'name' so that we can test multi-column # cases (which require some tricky SQL transformations under the covers). ->>> xx = Item(name='four', creator=a2) +>>> xx = Item(name='four', creator=a2, note=n1) >>> xx.save() >>> Item.objects.exclude(name='two').values('creator', 'name').distinct().count() 4 @@ -206,5 +277,40 @@ Bug #2400 Bug #2496 >>> Item.objects.extra(tables=['queries_author']).select_related().order_by('name')[:1] [<Item: four>] + +Bug #2076 +# Ordering on related tables should be possible, even if the table is not +# otherwise involved. +>>> Item.objects.order_by('note__note', 'name') +[<Item: two>, <Item: four>, <Item: one>, <Item: three>] + +# Ordering on a related field should use the remote model's default ordering as +# a final step. +>>> Author.objects.order_by('extra', '-name') +[<Author: a2>, <Author: a1>, <Author: a4>, <Author: a3>] + +# If the remote model does not have a default ordering, we order by its 'id' +# field. +>>> Item.objects.order_by('creator', 'name') +[<Item: one>, <Item: three>, <Item: two>, <Item: four>] + +# Cross model ordering is possible in Meta, too. +>>> Ranking.objects.all() +[<Ranking: 3: a1>, <Ranking: 2: a2>, <Ranking: 1: a3>] +>>> Ranking.objects.all().order_by('rank') +[<Ranking: 1: a3>, <Ranking: 2: a2>, <Ranking: 3: a1>] + +>>> Cover.objects.all() +[<Cover: first>, <Cover: second>] + +Bugs #2874, #3002 +>>> qs = Item.objects.select_related().order_by('note__note', 'name') +>>> list(qs) +[<Item: two>, <Item: four>, <Item: one>, <Item: three>] + +# This is also a good select_related() test because there are multiple Note +# entries in the SQL. The two Note items should be different. +>>> qs[0].note, qs[0].creator.extra.note +(<Note: n2>, <Note: n1>) """} |
