summaryrefslogtreecommitdiff
path: root/django/db/models
diff options
context:
space:
mode:
authorAnssi Kääriäinen <akaariai@gmail.com>2014-03-01 21:21:57 +0200
committerMarc Tamlyn <marc.tamlyn@gmail.com>2014-03-07 14:52:13 +0000
commit219d928852c256a81d09dbaa29ed4cec42d2fdfa (patch)
tree579c7d7fe66591e66c96fb406ba2d25a8ede5a91 /django/db/models
parenta0f252520291924f8fb7cb0d85f1680294508560 (diff)
Fixed #21863 -- supplemented get_lookup() with get_transform()
Also fixed #22124 -- Expanded explanation of exactly what is going on in as_sql() methods.
Diffstat (limited to 'django/db/models')
-rw-r--r--django/db/models/lookups.py16
-rw-r--r--django/db/models/sql/datastructures.py3
-rw-r--r--django/db/models/sql/query.py29
3 files changed, 30 insertions, 18 deletions
diff --git a/django/db/models/lookups.py b/django/db/models/lookups.py
index 993f5a92ca..797f767a97 100644
--- a/django/db/models/lookups.py
+++ b/django/db/models/lookups.py
@@ -9,11 +9,11 @@ from django.utils.six.moves import xrange
class RegisterLookupMixin(object):
- def get_lookup(self, lookup_name):
+ def _get_lookup(self, lookup_name):
try:
return self.class_lookups[lookup_name]
except KeyError:
- # To allow for inheritance, check parent class class lookups.
+ # To allow for inheritance, check parent class' class_lookups.
for parent in inspect.getmro(self.__class__):
if not 'class_lookups' in parent.__dict__:
continue
@@ -26,6 +26,18 @@ class RegisterLookupMixin(object):
return self.output_type.get_lookup(lookup_name)
return None
+ def get_lookup(self, lookup_name):
+ found = self._get_lookup(lookup_name)
+ if found is not None and not issubclass(found, Lookup):
+ return None
+ return found
+
+ def get_transform(self, lookup_name):
+ found = self._get_lookup(lookup_name)
+ if found is not None and not issubclass(found, Transform):
+ return None
+ return found
+
@classmethod
def register_lookup(cls, lookup):
if not 'class_lookups' in cls.__dict__:
diff --git a/django/db/models/sql/datastructures.py b/django/db/models/sql/datastructures.py
index 421c3cd860..634edf2477 100644
--- a/django/db/models/sql/datastructures.py
+++ b/django/db/models/sql/datastructures.py
@@ -24,6 +24,9 @@ class Col(object):
def get_lookup(self, name):
return self.output_type.get_lookup(name)
+ def get_transform(self, name):
+ return self.output_type.get_transform(name)
+
def prepare(self):
return self
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 7bfdceb183..25ebe5598e 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -1088,24 +1088,21 @@ class Query(object):
lookups = lookups[:]
while lookups:
lookup = lookups[0]
- next = lhs.get_lookup(lookup)
+ if len(lookups) == 1:
+ final_lookup = lhs.get_lookup(lookup)
+ if final_lookup:
+ return final_lookup(lhs, rhs)
+ # We didn't find a lookup, so we are going to try get_transform
+ # + get_lookup('exact').
+ lookups.append('exact')
+ next = lhs.get_transform(lookup)
if next:
- if len(lookups) == 1:
- # This was the last lookup, so return value lookup.
- if issubclass(next, Transform):
- lookups.append('exact')
- lhs = next(lhs, lookups)
- else:
- return next(lhs, rhs)
- else:
- lhs = next(lhs, lookups)
- # A field's get_lookup() can return None to opt for backwards
- # compatibility path.
- elif len(lookups) > 2:
- raise FieldError(
- "Unsupported lookup for field '%s'" % lhs.output_type.name)
+ lhs = next(lhs, lookups)
else:
- return None
+ raise FieldError(
+ "Unsupported lookup '%s' for %s or join on the field not "
+ "permitted." %
+ (lookup, lhs.output_type.__class__.__name__))
lookups = lookups[1:]
def build_filter(self, filter_expr, branch_negated=False, current_negated=False,