Opened 17 years ago

Closed 17 years ago

#3248 closed defect (duplicate)

order_by for a related table generates wrong query if the requested ordering field has the same name as the related class

Reported by: Nikolaus Schlemm <nikl@…> Owned by: Adrian Holovaty
Component: Database layer (models, ORM) Version: dev
Severity: normal Keywords: order_by
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

reproducible by:

  1. start an app "orderbug" with the following models:
    class Category(models.Model):
        category = models.CharField(maxlength=255)
    
    
    class Post(models.Model):
        category = models.ForeignKey(Category)
    
  2. install it
  3. run the following in the interpreter
    In [1]: from orderbug.models import Post
    
    In [2]: Post.objects.order_by('orderbug_category.category')
    ---------------------------------------------------------------------------
    pysqlite2.dbapi2.OperationalError                          Traceback (most recent call last)
    
    /home/nikl/dev/django/testproject/<ipython console> 
    
    /usr/lib/python2.4/site-packages/IPython/Prompts.py in __call__(self, arg)
        512 
        513             # and now call a possibly user-defined print mechanism
    --> 514             manipulated_val = self.display(arg)
        515             
        516             # user display hooks can change the variable to be stored in
    
    /usr/lib/python2.4/site-packages/IPython/Prompts.py in _display(self, arg)
        536         """
        537 
    --> 538         return self.shell.hooks.result_display(arg)
        539 
        540     # Assign the default display method:
    
    /usr/lib/python2.4/site-packages/IPython/hooks.py in __call__(self, *args, **kw)
        131             #print "prio",prio,"cmd",cmd #dbg
        132             try:
    --> 133                 ret = cmd(*args, **kw)
        134                 return ret
        135             except ipapi.TryNext, exc:
    
    /usr/lib/python2.4/site-packages/IPython/hooks.py in result_display(self, arg)
        152     
        153     if self.rc.pprint:
    --> 154         out = pformat(arg)
        155         if '\n' in out:
        156             # So that multi-line strings line up with the left column of
    
    /home/nikl/dev/django/testproject/pprint.py in pformat(self, object)
        108     def pformat(self, object):
        109         sio = _StringIO()
    --> 110         self._format(object, sio, 0, 0, {}, 0)
        111         return sio.getvalue()
        112 
    
    /home/nikl/dev/django/testproject/pprint.py in _format(self, object, stream, indent, allowance, context, level)
        126             self._readable = False
        127             return
    --> 128         rep = self._repr(object, context, level - 1)
        129         typ = _type(object)
        130         sepLines = _len(rep) > (self._width - 1 - indent - allowance)
    
    /home/nikl/dev/django/testproject/pprint.py in _repr(self, object, context, level)
        192     def _repr(self, object, context, level):
        193         repr, readable, recursive = self.format(object, context.copy(),
    --> 194                                                 self._depth, level)
        195         if not readable:
        196             self._readable = False
    
    /home/nikl/dev/django/testproject/pprint.py in format(self, object, context, maxlevels, level)
        204         and whether the object represents a recursive construct.
        205         """
    --> 206         return _safe_repr(object, context, maxlevels, level)
        207 
        208 
    
    /home/nikl/dev/django/testproject/pprint.py in _safe_repr(object, context, maxlevels, level)
        289         return format % _commajoin(components), readable, recursive
        290 
    --> 291     rep = repr(object)
        292     return rep, (rep and not rep.startswith('<')), False
        293 
    
    /home/nikl/site-packages/django/db/models/query.py in __repr__(self)
         95 
         96     def __repr__(self):
    ---> 97         return repr(self._get_data())
         98 
         99     def __len__(self):
    
    /home/nikl/site-packages/django/db/models/query.py in _get_data(self)
        428     def _get_data(self):
        429         if self._result_cache is None:
    --> 430             self._result_cache = list(self.iterator())
        431         return self._result_cache
        432 
    
    /home/nikl/site-packages/django/db/models/query.py in iterator(self)
        170         cursor = connection.cursor()
        171         select, sql, params = self._get_sql_clause()
    --> 172         cursor.execute("SELECT " + (self._distinct and "DISTINCT " or "") + ",".join(select) + sql, params)
        173         fill_cache = self._select_related
        174         index_end = len(self.model._meta.fields)
    
    /home/nikl/site-packages/django/db/backends/util.py in execute(self, sql, params)
         10         start = time()
         11         try:
    ---> 12             return self.cursor.execute(sql, params)
         13         finally:
         14             stop = time()
    
    /home/nikl/site-packages/django/db/backends/sqlite3/base.py in execute(self, query, params)
         90     def execute(self, query, params=()):
         91         query = self.convert_query(query, len(params))
    ---> 92         return Database.Cursor.execute(self, query, params)
         93 
         94     def executemany(self, query, param_list):
    
    OperationalError: no such column: orderbug_category.category_id
    

Change History (2)

comment:1 by (none), 17 years ago

milestone: Version 1.0

Milestone Version 1.0 deleted

comment:2 by mir@…, 17 years ago

Resolution: duplicate
Status: newclosed

duplicate of #2210

The correct usage in your case is order_by('category__category'). This does not currently work, but #2210 is about the same thing (and has a working patch!)

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