mirror of
https://github.com/django/django.git
synced 2025-07-07 03:09:22 +00:00
queryset-refactor: Fixed a possibility of shooting oneself in the foot and
creating infinite recursion with select_related(). Refs #3045, #3288. git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@6521 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
3429fc0ff2
commit
8c10e0d00e
@ -294,7 +294,8 @@ class _QuerySet(object):
|
|||||||
"""Returns a new QuerySet instance that will select related objects."""
|
"""Returns a new QuerySet instance that will select related objects."""
|
||||||
obj = self._clone()
|
obj = self._clone()
|
||||||
obj.query.select_related = true_or_false
|
obj.query.select_related = true_or_false
|
||||||
obj.query.max_depth = depth
|
if depth:
|
||||||
|
obj.query.max_depth = depth
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
def order_by(self, *field_names):
|
def order_by(self, *field_names):
|
||||||
|
@ -87,7 +87,10 @@ class Query(object):
|
|||||||
self.low_mark, self.high_mark = 0, None # Used for offset/limit
|
self.low_mark, self.high_mark = 0, None # Used for offset/limit
|
||||||
self.distinct = False
|
self.distinct = False
|
||||||
self.select_related = False
|
self.select_related = False
|
||||||
self.max_depth = 0
|
|
||||||
|
# Arbitrary maximum limit for select_related to prevent infinite
|
||||||
|
# recursion. Can be changed by the depth parameter to select_related().
|
||||||
|
self.max_depth = 5
|
||||||
|
|
||||||
# These are for extensions. The contents are more or less appended
|
# These are for extensions. The contents are more or less appended
|
||||||
# verbatim to the appropriate clause.
|
# verbatim to the appropriate clause.
|
||||||
|
@ -80,6 +80,14 @@ class Cover(models.Model):
|
|||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.title
|
return self.title
|
||||||
|
|
||||||
|
# Some funky cross-linked models for testing a couple of infinite recursion
|
||||||
|
# cases.
|
||||||
|
class X(models.Model):
|
||||||
|
y = models.ForeignKey('Y')
|
||||||
|
|
||||||
|
class Y(models.Model):
|
||||||
|
x1 = models.ForeignKey(X, related_name='y1')
|
||||||
|
|
||||||
__test__ = {'API_TESTS':"""
|
__test__ = {'API_TESTS':"""
|
||||||
>>> t1 = Tag(name='t1')
|
>>> t1 = Tag(name='t1')
|
||||||
>>> t1.save()
|
>>> t1.save()
|
||||||
@ -353,9 +361,18 @@ True
|
|||||||
>>> ExtraInfo.objects.values('note')
|
>>> ExtraInfo.objects.values('note')
|
||||||
[{'note': 1}, {'note': 2}]
|
[{'note': 1}, {'note': 2}]
|
||||||
|
|
||||||
# Bug 5261
|
Bug #5261
|
||||||
>>> Note.objects.exclude(Q())
|
>>> Note.objects.exclude(Q())
|
||||||
[<Note: n1>, <Note: n2>, <Note: n3>]
|
[<Note: n1>, <Note: n2>, <Note: n3>]
|
||||||
|
|
||||||
|
Bug #3045, #3288
|
||||||
|
Once upon a time, select_related() with circular relations would loop
|
||||||
|
infinitely if you forgot to specify "depth". Now we set an arbitrary default
|
||||||
|
upper bound.
|
||||||
|
>>> X.objects.all()
|
||||||
|
[]
|
||||||
|
>>> X.objects.select_related()
|
||||||
|
[]
|
||||||
|
|
||||||
"""}
|
"""}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user