Fixed #24654 -- Based ordering circular references detection on columns.
Thanks to Elmar Bucher for the report and Tim for the review.
This commit is contained in:
parent
ffe83d16bd
commit
b44ed404c7
|
@ -567,7 +567,7 @@ class SQLCompiler(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(self.query.alias_map[j].table_name for j in joins)
|
join_tuple = tuple(getattr(self.query.alias_map[j], 'join_cols', None) 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)
|
||||||
|
|
|
@ -25,6 +25,7 @@ class Author(models.Model):
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
author = models.ForeignKey(Author, null=True)
|
author = models.ForeignKey(Author, null=True)
|
||||||
|
second_author = models.ForeignKey(Author, null=True)
|
||||||
headline = models.CharField(max_length=100)
|
headline = models.CharField(max_length=100)
|
||||||
pub_date = models.DateTimeField()
|
pub_date = models.DateTimeField()
|
||||||
|
|
||||||
|
@ -33,3 +34,16 @@ class Article(models.Model):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.headline
|
return self.headline
|
||||||
|
|
||||||
|
|
||||||
|
class OrderedByAuthorArticle(Article):
|
||||||
|
class Meta:
|
||||||
|
proxy = True
|
||||||
|
ordering = ('author', 'second_author')
|
||||||
|
|
||||||
|
|
||||||
|
class Reference(models.Model):
|
||||||
|
article = models.ForeignKey(OrderedByAuthorArticle)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = ('article',)
|
||||||
|
|
|
@ -6,7 +6,7 @@ from operator import attrgetter
|
||||||
from django.db.models import F
|
from django.db.models import F
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
from .models import Article, Author
|
from .models import Article, Author, Reference
|
||||||
|
|
||||||
|
|
||||||
class OrderingTests(TestCase):
|
class OrderingTests(TestCase):
|
||||||
|
@ -307,3 +307,20 @@ class OrderingTests(TestCase):
|
||||||
],
|
],
|
||||||
attrgetter("headline")
|
attrgetter("headline")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_related_ordering_duplicate_table_reference(self):
|
||||||
|
"""
|
||||||
|
An ordering referencing a model with an ordering referencing a model
|
||||||
|
multiple time no circular reference should be detected (#24654).
|
||||||
|
"""
|
||||||
|
first_author = Author.objects.create()
|
||||||
|
second_author = Author.objects.create()
|
||||||
|
self.a1.author = first_author
|
||||||
|
self.a1.second_author = second_author
|
||||||
|
self.a1.save()
|
||||||
|
self.a2.author = second_author
|
||||||
|
self.a2.second_author = first_author
|
||||||
|
self.a2.save()
|
||||||
|
r1 = Reference.objects.create(article_id=self.a1.pk)
|
||||||
|
r2 = Reference.objects.create(article_id=self.a2.pk)
|
||||||
|
self.assertQuerysetEqual(Reference.objects.all(), [r2, r1], lambda x: x)
|
||||||
|
|
Loading…
Reference in New Issue