diff options
| author | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2008-06-29 02:36:18 +0000 |
|---|---|---|
| committer | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2008-06-29 02:36:18 +0000 |
| commit | bb2182453b49157fb6fba4de6d3c53a09f73d74b (patch) | |
| tree | 502104407d15efb2dadabd30d95e71b9ede44a34 /tests | |
| parent | d800c0b031aea81ee6f3a7c28ef88c05494e4eea (diff) | |
Fixed handling of multiple fields in a model pointing to the same related model.
Thanks to ElliotM, mk and oyvind for some excellent test cases for this. Fixed #7110, #7125.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7778 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/regressiontests/many_to_one_regress/models.py | 40 | ||||
| -rw-r--r-- | tests/regressiontests/select_related_regress/__init__.py | 0 | ||||
| -rw-r--r-- | tests/regressiontests/select_related_regress/models.py | 60 |
3 files changed, 100 insertions, 0 deletions
diff --git a/tests/regressiontests/many_to_one_regress/models.py b/tests/regressiontests/many_to_one_regress/models.py index 4e49df1555..429bdd7558 100644 --- a/tests/regressiontests/many_to_one_regress/models.py +++ b/tests/regressiontests/many_to_one_regress/models.py @@ -28,6 +28,24 @@ class Child(models.Model): parent = models.ForeignKey(Parent) +# Multiple paths to the same model (#7110, #7125) +class Category(models.Model): + name = models.CharField(max_length=20) + + def __unicode__(self): + return self.name + +class Record(models.Model): + category = models.ForeignKey(Category) + +class Relation(models.Model): + left = models.ForeignKey(Record, related_name='left_set') + right = models.ForeignKey(Record, related_name='right_set') + + def __unicode__(self): + return u"%s - %s" % (self.left.category.name, self.right.category.name) + + __test__ = {'API_TESTS':""" >>> Third.objects.create(id='3', name='An example') <Third: Third object> @@ -73,4 +91,26 @@ Traceback (most recent call last): ... ValueError: Cannot assign "<First: First object>": "Child.parent" must be a "Parent" instance. +# Test of multiple ForeignKeys to the same model (bug #7125) + +>>> c1 = Category.objects.create(name='First') +>>> c2 = Category.objects.create(name='Second') +>>> c3 = Category.objects.create(name='Third') +>>> r1 = Record.objects.create(category=c1) +>>> r2 = Record.objects.create(category=c1) +>>> r3 = Record.objects.create(category=c2) +>>> r4 = Record.objects.create(category=c2) +>>> r5 = Record.objects.create(category=c3) +>>> r = Relation.objects.create(left=r1, right=r2) +>>> r = Relation.objects.create(left=r3, right=r4) +>>> r = Relation.objects.create(left=r1, right=r3) +>>> r = Relation.objects.create(left=r5, right=r2) +>>> r = Relation.objects.create(left=r3, right=r2) + +>>> Relation.objects.filter(left__category__name__in=['First'], right__category__name__in=['Second']) +[<Relation: First - Second>] + +>>> Category.objects.filter(record__left_set__right__category__name='Second').order_by('name') +[<Category: First>, <Category: Second>] + """} diff --git a/tests/regressiontests/select_related_regress/__init__.py b/tests/regressiontests/select_related_regress/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/regressiontests/select_related_regress/__init__.py diff --git a/tests/regressiontests/select_related_regress/models.py b/tests/regressiontests/select_related_regress/models.py new file mode 100644 index 0000000000..1688053e2d --- /dev/null +++ b/tests/regressiontests/select_related_regress/models.py @@ -0,0 +1,60 @@ +from django.db import models + +class Building(models.Model): + name = models.CharField(max_length=10) + + def __unicode__(self): + return u"Building: %s" % self.name + +class Device(models.Model): + building = models.ForeignKey('Building') + name = models.CharField(max_length=10) + + def __unicode__(self): + return u"device '%s' in building %s" % (self.name, self.building) + +class Port(models.Model): + device = models.ForeignKey('Device') + number = models.CharField(max_length=10) + + def __unicode__(self): + return u"%s/%s" % (self.device.name, self.number) + +class Connection(models.Model): + start = models.ForeignKey(Port, related_name='connection_start', + unique=True) + end = models.ForeignKey(Port, related_name='connection_end', unique=True) + + def __unicode__(self): + return u"%s to %s" % (self.start, self.end) + +__test__ = {'API_TESTS': """ +Regression test for bug #7110. When using select_related(), we must query the +Device and Building tables using two different aliases (each) in order to +differentiate the start and end Connection fields. The net result is that both +the "connections = ..." queries here should give the same results. + +>>> b=Building.objects.create(name='101') +>>> dev1=Device.objects.create(name="router", building=b) +>>> dev2=Device.objects.create(name="switch", building=b) +>>> dev3=Device.objects.create(name="server", building=b) +>>> port1=Port.objects.create(number='4',device=dev1) +>>> port2=Port.objects.create(number='7',device=dev2) +>>> port3=Port.objects.create(number='1',device=dev3) +>>> c1=Connection.objects.create(start=port1, end=port2) +>>> c2=Connection.objects.create(start=port2, end=port3) + +>>> connections=Connection.objects.filter(start__device__building=b, end__device__building=b).order_by('id') +>>> [(c.id, unicode(c.start), unicode(c.end)) for c in connections] +[(1, u'router/4', u'switch/7'), (2, u'switch/7', u'server/1')] + +>>> connections=Connection.objects.filter(start__device__building=b, end__device__building=b).select_related().order_by('id') +>>> [(c.id, unicode(c.start), unicode(c.end)) for c in connections] +[(1, u'router/4', u'switch/7'), (2, u'switch/7', u'server/1')] + +# This final query should only join seven tables (port, device and building +# twice each, plus connection once). +>>> connections.query.count_active_tables() +7 + +"""} |
