diff options
| author | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2008-04-16 04:32:56 +0000 |
|---|---|---|
| committer | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2008-04-16 04:32:56 +0000 |
| commit | 36bbebc739de00f768e2011afb8fe3b9ab15331f (patch) | |
| tree | 4602dc2bd85a333c5d9a705a10f0f07ada9ac861 | |
| parent | 96d643548e7c161590b66ef893eafde5f7f35bcc (diff) | |
queryset-refactor: Detect infinite ordering loops when relations refer to 'self'.
git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@7429 bcc190cf-cafb-0310-a4f2-bffc1f526a37
| -rw-r--r-- | django/db/models/sql/query.py | 2 | ||||
| -rw-r--r-- | tests/regressiontests/queries/models.py | 13 |
2 files changed, 13 insertions, 2 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index d804075926..4cc1500c94 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -535,7 +535,7 @@ class Query(object): # Firstly, avoid infinite loops. if not already_seen: already_seen = set() - join_tuple = tuple(joins) + join_tuple = tuple([self.alias_map[j][TABLE_NAME] for j in joins]) if join_tuple in already_seen: raise FieldError('Infinite loop caused by ordering.') already_seen.add(join_tuple) diff --git a/tests/regressiontests/queries/models.py b/tests/regressiontests/queries/models.py index f80d1eb827..487bdb15f2 100644 --- a/tests/regressiontests/queries/models.py +++ b/tests/regressiontests/queries/models.py @@ -111,6 +111,12 @@ class LoopY(models.Model): class Meta: ordering = ['x'] +class LoopZ(models.Model): + z = models.ForeignKey('self') + + class Meta: + ordering = ['z'] + __test__ = {'API_TESTS':""" >>> t1 = Tag(name='t1') >>> t1.save() @@ -426,9 +432,14 @@ Traceback (most recent call last): ... FieldError: Infinite loop caused by ordering. +>>> LoopZ.objects.all() +Traceback (most recent call last): +... +FieldError: Infinite loop caused by ordering. + # ... but you can still order in a non-recursive fashion amongst linked fields # (the previous test failed because the default ordering was recursive). ->>> LoopX.objects.all().order_by('y__x__id') +>>> LoopX.objects.all().order_by('y__x__y__x__id') [] # If the remote model does not have a default ordering, we order by its 'id' |
