Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

queryset-refactor: Implemented filtering by output columns specified in

extra(select=...). Refs #4002.


git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@6762 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 79653a414857e4f93918051843afbc1f7c9a7f99 1 parent a241817
@malcolmt malcolmt authored
View
12 django/db/models/sql/query.py
@@ -692,8 +692,16 @@ def add_filter(self, filter_expr, connection=AND, negate=False):
opts = self.model._meta
alias = self.join((None, opts.db_table, None, None))
- field, target, unused, join_list, nullable = self.setup_joins(parts,
- opts, alias, (connection == AND))
+ try:
+ field, target, unused, join_list, nullable = self.setup_joins(parts,
+ opts, alias, (connection == AND))
+ except TypeError, e:
+ if len(parts) != 1 or parts[0] not in self.extra_select:
+ raise e
+ # Filtering on some alias from extra(select=...)
+ self.where.add([None, parts[0], None, lookup_type, value],
+ connection)
+ return
col = target.column
alias = join_list[-1][-1]
View
6 django/db/models/sql/where.py
@@ -5,6 +5,7 @@
from django.utils import tree
from django.db import connection
+from django.db.models.fields import Field
from datastructures import EmptyResultSet
# Connection types
@@ -96,7 +97,10 @@ def make_atom(self, child, qn):
else:
format = '%s %s'
- params = field.get_db_prep_lookup(lookup_type, value)
+ if field:
+ params = field.get_db_prep_lookup(lookup_type, value)
+ else:
+ params = Field().get_db_prep_lookup(lookup_type, value)
if lookup_type in connection.operators:
return (format % (field_sql,
View
13 tests/regressiontests/queries/models.py
@@ -404,5 +404,18 @@ class Y(models.Model):
... params.reverse()
>>> Item.objects.extra(select=SortedDict(s), params=params).values('a','b')[0]
{'a': u'one', 'b': u'two'}
+
+Bug #4002
+Attributes used in extra(select=...) are available for use in subsequent
+order_by() and filter() calls.
+
+# Order by the number of tags attached to an item.
+>>> l = Item.objects.extra(select={'count': 'select count(*) from queries_item_tags where queries_item_tags.item_id = queries_item.id'}).order_by('-count')
+>>> [o.count for o in l]
+[2, 2, 1, 0]
+
+# Filter those items that have exactly one tag attacjed.
+>>> Item.objects.extra(select={'count': 'select count(*) from queries_item_tags where queries_item_tags.item_id = queries_item.id'}).filter(count=1)
+[<Item: four>]
"""}

0 comments on commit 79653a4

Please sign in to comment.
Something went wrong with that request. Please try again.