1
0
mirror of https://github.com/django/django.git synced 2025-07-06 10:49:17 +00:00

queryset-refactor: Added an order_by parameter to extra(). Refs #2076.

git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@6511 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2007-10-15 00:29:27 +00:00
parent a1d160e2ea
commit 201c15dcb6
3 changed files with 24 additions and 11 deletions

View File

@ -313,11 +313,10 @@ class _QuerySet(object):
obj.query.distinct = true_or_false obj.query.distinct = true_or_false
return obj return obj
def extra(self, select=None, where=None, params=None, tables=None): def extra(self, select=None, where=None, params=None, tables=None,
order_by=None):
""" """
Add extra SQL fragments to the query. These are applied more or less Add extra SQL fragments to the query.
verbatim (no quoting, no alias renaming, etc), so care should be taken
when using extra() with other complex filters and combinations.
""" """
assert self.query.can_filter(), \ assert self.query.can_filter(), \
"Cannot change a query once a slice has been taken" "Cannot change a query once a slice has been taken"
@ -330,6 +329,8 @@ class _QuerySet(object):
clone.query.extra_params.extend(params) clone.query.extra_params.extend(params)
if tables: if tables:
clone.query.extra_tables.extend(tables) clone.query.extra_tables.extend(tables)
if order_by:
clone.query.extra_order_by.extend(order_by)
return clone return clone
################### ###################

View File

@ -378,9 +378,14 @@ class Query(object):
for alias in self.tables: for alias in self.tables:
if not self.alias_map[alias][ALIAS_REFCOUNT]: if not self.alias_map[alias][ALIAS_REFCOUNT]:
continue continue
name, alias, join_type, lhs, lhs_col, col = \ join = self.alias_map[alias][ALIAS_JOIN]
self.alias_map[alias][ALIAS_JOIN] if join:
alias_str = (alias != name and ' AS %s' % alias or '') name, alias, join_type, lhs, lhs_col, col = join
alias_str = (alias != name and ' AS %s' % alias or '')
else:
join_type = None
alias_str = ''
name = alias
if join_type: if join_type:
result.append('%s %s%s ON (%s.%s = %s.%s)' result.append('%s %s%s ON (%s.%s = %s.%s)'
% (join_type, qn(name), alias_str, qn(lhs), % (join_type, qn(name), alias_str, qn(lhs),
@ -464,8 +469,8 @@ class Query(object):
def find_ordering_name(self, name, opts, alias=None, default_order='ASC'): def find_ordering_name(self, name, opts, alias=None, default_order='ASC'):
""" """
Returns the table alias (the name might not be unambiguous, the alias Returns the table alias (the name might be ambiguous, the alias will
will be) and column name for ordering by the given 'name' parameter. not be) and column name for ordering by the given 'name' parameter.
The 'name' is of the form 'field1__field2__...__fieldN'. The 'name' is of the form 'field1__field2__...__fieldN'.
""" """
name, order = get_order_dir(name, default_order) name, order = get_order_dir(name, default_order)

View File

@ -289,6 +289,11 @@ Bug #2076
>>> Author.objects.order_by('extra', '-name') >>> Author.objects.order_by('extra', '-name')
[<Author: a2>, <Author: a1>, <Author: a4>, <Author: a3>] [<Author: a2>, <Author: a1>, <Author: a4>, <Author: a3>]
# Using remote model default ordering can span multiple models (in this case,
# Cover is ordered by Item's default, which uses Note's default).
>>> Cover.objects.all()
[<Cover: first>, <Cover: second>]
# 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'
# field. # field.
>>> Item.objects.order_by('creator', 'name') >>> Item.objects.order_by('creator', 'name')
@ -300,8 +305,10 @@ Bug #2076
>>> Ranking.objects.all().order_by('rank') >>> Ranking.objects.all().order_by('rank')
[<Ranking: 1: a3>, <Ranking: 2: a2>, <Ranking: 3: a1>] [<Ranking: 1: a3>, <Ranking: 2: a2>, <Ranking: 3: a1>]
>>> Cover.objects.all() # Ordering of extra() pieces is possible, too and you can mix extra fields and
[<Cover: first>, <Cover: second>] # model fields in the ordering.
>>> Ranking.objects.extra(tables=['django_site'], order_by=['-django_site.id', 'rank'])
[<Ranking: 1: a3>, <Ranking: 2: a2>, <Ranking: 3: a1>]
Bugs #2874, #3002 Bugs #2874, #3002
>>> qs = Item.objects.select_related().order_by('note__note', 'name') >>> qs = Item.objects.select_related().order_by('note__note', 'name')