Opened 12 years ago

Closed 12 years ago

Last modified 12 years ago

#7101 closed (invalid)

ordering ForeignKey(self) =FieldError: Infinite loop caused by ordering.

Reported by: Carl Karsten <carl@…> Owned by: nobody
Component: Core (Other) Version: master
Severity: Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


r7477 caused this code to error. If I trimmed to much, let me know and I'll mock up a reproducible setup.

class NavBarEntry(models.Model):
    name   = models.CharField(max_length=50,
                              help_text="text seen in the menu")
    parent = models.ForeignKey('self', related_name='children',
                               blank=True, null=True,

    class Meta:
        ordering = ('parent', )
Traceback (most recent call last):

  File "/home/juser/django/core/servers/", line 277, in run
    self.result = application(self.environ, self.start_response)

  File "/home/juser/django/core/servers/", line 631, in __call__
    return self.application(environ, start_response)

  File "/home/juser/django/core/handlers/", line 209, in __call__
    response = middleware_method(request, response)

  File "/home/juser/django/contrib/flatpages/", line 10, in process_response
    return flatpage(request, request.path)

  File "/home/juser/django/contrib/flatpages/", line 42, in flatpage
    'flatpage': f,

  File "/home/juser/django/template/", line 103, in __init__

  File "/home/juser/wineshow/navbar/", line 39, in navbars
    nav    = get_navtree(request.user, MAX_DEPTH)

  File "/home/juser/wineshow/navbar/", line 167, in get_navtree
    data = generate_navtree(user, maxdepth)

  File "/home/juser/wineshow/navbar/", line 153, in generate_navtree
    tree = navlevel(, maxdepth)

  File "/home/juser/wineshow/navbar/", line 152, in navlevel
    for ent in base.filter(permQ).distinct() ]

  File "/home/juser/django/db/models/", line 67, in _result_iter

  File "/home/juser/django/db/models/", line 479, in _fill_cache

  File "/home/juser/django/db/models/", line 151, in iterator
    for row in self.query.results_iter():

  File "/home/juser/django/db/models/sql/", line 182, in results_iter
    for rows in self.execute_sql(MULTI):

  File "/home/juser/django/db/models/sql/", line 1432, in execute_sql
    sql, params = self.as_sql()

  File "/home/juser/django/db/models/sql/", line 229, in as_sql
    ordering = self.get_ordering()

  File "/home/juser/django/db/models/sql/", line 564, in get_ordering
    self.model._meta, default_order=asc):

  File "/home/juser/django/db/models/sql/", line 608, in find_ordering_name
    order, already_seen))

  File "/home/juser/django/db/models/sql/", line 602, in find_ordering_name
    raise FieldError('Infinite loop caused by ordering.')

FieldError: Infinite loop caused by ordering.

Change History (5)

comment:1 Changed 12 years ago by Malcolm Tredinnick

Resolution: invalid
Status: newclosed

That code was already broken, but you just hadn't noticed. Django is now correctly reporting the error. If you order by the parent, then the parents should be order by their parents and so on. Since that's impossible to encode in SQL, previous versions of Django were returning only a single level of ordering, which was very inconsistent.

Either remove the infinite loop or use order_by('parent_id') if you want a workaround to simulate the previous ambiguous behaviour.

comment:2 Changed 12 years ago by dougn

NOTE: parent_id does not work as:

FieldError: Cannot resolve keyword 'parent_id' into field. Choices are: children, groups, id, name, order, parent, title, url, user_type

Currently there is no workaround for this.

comment:3 Changed 12 years ago by Malcolm Tredinnick

*sigh* It was a typo. Use parent__id (double underscore). You can always specify ordering that ends at any non-related field.

comment:4 Changed 12 years ago by Malcolm Tredinnick

Cc: malcolm@… removed

comment:5 Changed 12 years ago by dougn

*duh* I feel like an idiot now.

Note: See TracTickets for help on using tickets.
Back to Top