mirror of
https://github.com/django/django.git
synced 2025-07-06 18:59:13 +00:00
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
This commit is contained in:
parent
96d643548e
commit
36bbebc739
@ -535,7 +535,7 @@ class Query(object):
|
|||||||
# Firstly, avoid infinite loops.
|
# Firstly, avoid infinite loops.
|
||||||
if not already_seen:
|
if not already_seen:
|
||||||
already_seen = set()
|
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:
|
if join_tuple in already_seen:
|
||||||
raise FieldError('Infinite loop caused by ordering.')
|
raise FieldError('Infinite loop caused by ordering.')
|
||||||
already_seen.add(join_tuple)
|
already_seen.add(join_tuple)
|
||||||
|
@ -111,6 +111,12 @@ class LoopY(models.Model):
|
|||||||
class Meta:
|
class Meta:
|
||||||
ordering = ['x']
|
ordering = ['x']
|
||||||
|
|
||||||
|
class LoopZ(models.Model):
|
||||||
|
z = models.ForeignKey('self')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = ['z']
|
||||||
|
|
||||||
__test__ = {'API_TESTS':"""
|
__test__ = {'API_TESTS':"""
|
||||||
>>> t1 = Tag(name='t1')
|
>>> t1 = Tag(name='t1')
|
||||||
>>> t1.save()
|
>>> t1.save()
|
||||||
@ -426,9 +432,14 @@ Traceback (most recent call last):
|
|||||||
...
|
...
|
||||||
FieldError: Infinite loop caused by ordering.
|
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
|
# ... but you can still order in a non-recursive fashion amongst linked fields
|
||||||
# (the previous test failed because the default ordering was recursive).
|
# (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'
|
# If the remote model does not have a default ordering, we order by its 'id'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user