diff options
Diffstat (limited to 'django')
| -rw-r--r-- | django/contrib/admin/filters.py | 3 | ||||
| -rw-r--r-- | django/contrib/admin/widgets.py | 1 | ||||
| -rw-r--r-- | django/contrib/gis/db/models/fields.py | 7 | ||||
| -rw-r--r-- | django/contrib/postgres/fields/jsonb.py | 7 | ||||
| -rw-r--r-- | django/contrib/postgres/fields/ranges.py | 2 | ||||
| -rw-r--r-- | django/contrib/postgres/lookups.py | 7 | ||||
| -rw-r--r-- | django/db/models/expressions.py | 2 | ||||
| -rw-r--r-- | django/db/models/fields/__init__.py | 58 | ||||
| -rw-r--r-- | django/db/models/fields/files.py | 5 | ||||
| -rw-r--r-- | django/db/models/fields/related_lookups.py | 14 | ||||
| -rw-r--r-- | django/db/models/fields/reverse_related.py | 7 | ||||
| -rw-r--r-- | django/db/models/lookups.py | 33 |
12 files changed, 50 insertions, 96 deletions
diff --git a/django/contrib/admin/filters.py b/django/contrib/admin/filters.py index bb9731bdfc..f986bca713 100644 --- a/django/contrib/admin/filters.py +++ b/django/contrib/admin/filters.py @@ -232,6 +232,9 @@ class BooleanFieldListFilter(FieldListFilter): self.lookup_val = request.GET.get(self.lookup_kwarg) self.lookup_val2 = request.GET.get(self.lookup_kwarg2) super(BooleanFieldListFilter, self).__init__(field, request, params, model, model_admin, field_path) + if (self.used_parameters and self.lookup_kwarg in self.used_parameters and + self.used_parameters[self.lookup_kwarg] in ('1', '0')): + self.used_parameters[self.lookup_kwarg] = bool(int(self.used_parameters[self.lookup_kwarg])) def expected_parameters(self): return [self.lookup_kwarg, self.lookup_kwarg2] diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py index 8967200318..e3553de70a 100644 --- a/django/contrib/admin/widgets.py +++ b/django/contrib/admin/widgets.py @@ -128,7 +128,6 @@ def url_params_from_lookup_dict(lookups): if isinstance(v, (tuple, list)): v = ','.join(str(x) for x in v) elif isinstance(v, bool): - # See django.db.fields.BooleanField.get_prep_lookup v = ('0', '1')[v] else: v = six.text_type(v) diff --git a/django/contrib/gis/db/models/fields.py b/django/contrib/gis/db/models/fields.py index 4fa9674419..8452a11c5f 100644 --- a/django/contrib/gis/db/models/fields.py +++ b/django/contrib/gis/db/models/fields.py @@ -316,13 +316,6 @@ class GeometryField(GeoSelectFormatMixin, BaseSpatialField): params = [connection.ops.Adapter(value)] return params - def get_prep_lookup(self, lookup_type, value): - if lookup_type == 'contains': - # 'contains' name might conflict with the "normal" contains lookup, - # for which the value is not prepared, but left as-is. - return self.get_prep_value(value) - return super(GeometryField, self).get_prep_lookup(lookup_type, value) - def get_db_prep_save(self, value, connection): "Prepares the value for saving in the database." if not value: diff --git a/django/contrib/postgres/fields/jsonb.py b/django/contrib/postgres/fields/jsonb.py index d580ea2efd..ae83d9e379 100644 --- a/django/contrib/postgres/fields/jsonb.py +++ b/django/contrib/postgres/fields/jsonb.py @@ -31,13 +31,6 @@ class JSONField(Field): return Json(value) return value - def get_prep_lookup(self, lookup_type, value): - if lookup_type in ('has_key', 'has_keys', 'has_any_keys'): - return value - if isinstance(value, (dict, list)): - return Json(value) - return super(JSONField, self).get_prep_lookup(lookup_type, value) - def validate(self, value, model_instance): super(JSONField, self).validate(value, model_instance) try: diff --git a/django/contrib/postgres/fields/ranges.py b/django/contrib/postgres/fields/ranges.py index 3816de84f1..ab7708d288 100644 --- a/django/contrib/postgres/fields/ranges.py +++ b/django/contrib/postgres/fields/ranges.py @@ -154,7 +154,7 @@ class RangeContainedBy(models.Lookup): return sql % (lhs, rhs), params def get_prep_lookup(self): - return RangeField().get_prep_lookup(self.lookup_name, self.rhs) + return RangeField().get_prep_value(self.rhs) models.DateField.register_lookup(RangeContainedBy) diff --git a/django/contrib/postgres/lookups.py b/django/contrib/postgres/lookups.py index 1a71725678..a39c9679e7 100644 --- a/django/contrib/postgres/lookups.py +++ b/django/contrib/postgres/lookups.py @@ -1,4 +1,5 @@ from django.db.models import Lookup, Transform +from django.utils.encoding import force_text from .search import SearchVector, SearchVectorExact, SearchVectorField @@ -29,14 +30,18 @@ class Overlap(PostgresSimpleLookup): class HasKey(PostgresSimpleLookup): lookup_name = 'has_key' operator = '?' + prepare_rhs = False class HasKeys(PostgresSimpleLookup): lookup_name = 'has_keys' operator = '?&' + def get_prep_lookup(self): + return [force_text(item) for item in self.rhs] -class HasAnyKeys(PostgresSimpleLookup): + +class HasAnyKeys(HasKeys): lookup_name = 'has_any_keys' operator = '?|' diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index b1133e24ea..df82d2ec58 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -213,7 +213,7 @@ class BaseExpression(object): def _prepare(self, field): """ - Hook used by Field.get_prep_lookup() to do custom preparation. + Hook used by Lookup.get_prep_lookup() to do custom preparation. """ return self diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 5951681e81..e567e12250 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -741,8 +741,7 @@ class Field(RegisterLookupMixin): """Returns field's value prepared for interacting with the database backend. - Used by the default implementations of ``get_db_prep_save``and - `get_db_prep_lookup``` + Used by the default implementations of get_db_prep_save(). """ if not prepared: value = self.get_prep_value(value) @@ -755,36 +754,6 @@ class Field(RegisterLookupMixin): return self.get_db_prep_value(value, connection=connection, prepared=False) - def get_prep_lookup(self, lookup_type, value): - """ - Perform preliminary non-db specific lookup checks and conversions - """ - if hasattr(value, '_prepare'): - return value._prepare(self) - - if lookup_type in { - 'iexact', 'contains', 'icontains', - 'startswith', 'istartswith', 'endswith', 'iendswith', - 'isnull', 'search', 'regex', 'iregex', - }: - return value - elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte'): - return self.get_prep_value(value) - elif lookup_type in ('range', 'in'): - return [self.get_prep_value(v) for v in value] - return self.get_prep_value(value) - - def get_db_prep_lookup(self, lookup_type, value, connection, - prepared=False): - """ - Returns field's value prepared for database lookup. - """ - if not prepared: - value = self.get_prep_lookup(lookup_type, value) - prepared = True - - return [value] - def has_default(self): """ Returns a boolean of whether this field has a default value. @@ -1049,20 +1018,11 @@ class BooleanField(Field): params={'value': value}, ) - def get_prep_lookup(self, lookup_type, value): - # Special-case handling for filters coming from a Web request (e.g. the - # admin interface). Only works for scalar values (not lists). If you're - # passing in a list, you might as well make things the right type when - # constructing the list. - if value in ('1', '0'): - value = bool(int(value)) - return super(BooleanField, self).get_prep_lookup(lookup_type, value) - def get_prep_value(self, value): value = super(BooleanField, self).get_prep_value(value) if value is None: return None - return bool(value) + return self.to_python(value) def formfield(self, **kwargs): # Unlike most fields, BooleanField figures out include_blank from @@ -1453,8 +1413,6 @@ class DateTimeField(DateField): # contribute_to_class is inherited from DateField, it registers # get_next_by_FOO and get_prev_by_FOO - # get_prep_lookup is inherited from DateField - def get_prep_value(self, value): value = super(DateTimeField, self).get_prep_value(value) value = self.to_python(value) @@ -2051,21 +2009,11 @@ class NullBooleanField(Field): params={'value': value}, ) - def get_prep_lookup(self, lookup_type, value): - # Special-case handling for filters coming from a Web request (e.g. the - # admin interface). Only works for scalar values (not lists). If you're - # passing in a list, you might as well make things the right type when - # constructing the list. - if value in ('1', '0'): - value = bool(int(value)) - return super(NullBooleanField, self).get_prep_lookup(lookup_type, - value) - def get_prep_value(self, value): value = super(NullBooleanField, self).get_prep_value(value) if value is None: return None - return bool(value) + return self.to_python(value) def formfield(self, **kwargs): defaults = { diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py index 3ba2c14325..f18e2f39b3 100644 --- a/django/db/models/fields/files.py +++ b/django/db/models/fields/files.py @@ -271,11 +271,6 @@ class FileField(Field): def get_internal_type(self): return "FileField" - def get_prep_lookup(self, lookup_type, value): - if hasattr(value, 'name'): - value = value.name - return super(FileField, self).get_prep_lookup(lookup_type, value) - def get_prep_value(self, value): "Returns field's value prepared for saving into a database." value = super(FileField, self).get_prep_value(value) diff --git a/django/db/models/fields/related_lookups.py b/django/db/models/fields/related_lookups.py index 0f5a8b5e21..3123e94073 100644 --- a/django/db/models/fields/related_lookups.py +++ b/django/db/models/fields/related_lookups.py @@ -44,15 +44,15 @@ class RelatedIn(In): if not isinstance(self.lhs, MultiColSource) and self.rhs_is_direct_value(): # If we get here, we are dealing with single-column relations. self.rhs = [get_normalized_value(val, self.lhs)[0] for val in self.rhs] - # We need to run the related field's get_prep_lookup(). Consider case + # We need to run the related field's get_prep_value(). Consider case # ForeignKey to IntegerField given value 'abc'. The ForeignKey itself # doesn't have validation for non-integers, so we must run validation # using the target field. if hasattr(self.lhs.output_field, 'get_path_info'): - # Run the target field's get_prep_lookup. We can safely assume there is + # Run the target field's get_prep_value. We can safely assume there is # only one as we don't get to the direct value branch otherwise. - self.rhs = self.lhs.output_field.get_path_info()[-1].target_fields[-1].get_prep_lookup( - self.lookup_name, self.rhs) + target_field = self.lhs.output_field.get_path_info()[-1].target_fields[-1] + self.rhs = [target_field.get_prep_value(v) for v in self.rhs] return super(RelatedIn, self).get_prep_lookup() def as_sql(self, compiler, connection): @@ -88,15 +88,15 @@ class RelatedLookupMixin(object): if not isinstance(self.lhs, MultiColSource) and self.rhs_is_direct_value(): # If we get here, we are dealing with single-column relations. self.rhs = get_normalized_value(self.rhs, self.lhs)[0] - # We need to run the related field's get_prep_lookup(). Consider case + # We need to run the related field's get_prep_value(). Consider case # ForeignKey to IntegerField given value 'abc'. The ForeignKey itself # doesn't have validation for non-integers, so we must run validation # using the target field. if hasattr(self.lhs.output_field, 'get_path_info'): # Get the target field. We can safely assume there is only one # as we don't get to the direct value branch otherwise. - self.rhs = self.lhs.output_field.get_path_info()[-1].target_fields[-1].get_prep_lookup( - self.lookup_name, self.rhs) + target_field = self.lhs.output_field.get_path_info()[-1].target_fields[-1] + self.rhs = target_field.get_prep_value(self.rhs) return super(RelatedLookupMixin, self).get_prep_lookup() diff --git a/django/db/models/fields/reverse_related.py b/django/db/models/fields/reverse_related.py index c477ab5a93..1554261246 100644 --- a/django/db/models/fields/reverse_related.py +++ b/django/db/models/fields/reverse_related.py @@ -110,9 +110,6 @@ class ForeignObjectRel(object): def one_to_one(self): return self.field.one_to_one - def get_prep_lookup(self, lookup_name, value): - return self.field.get_prep_lookup(lookup_name, value) - def get_lookup(self, lookup_name): return self.field.get_lookup(lookup_name) @@ -142,10 +139,6 @@ class ForeignObjectRel(object): (x._get_pk_val(), smart_text(x)) for x in self.related_model._default_manager.all() ] - def get_db_prep_lookup(self, lookup_type, value, connection, prepared=False): - # Defer to the actual field definition for db prep - return self.field.get_db_prep_lookup(lookup_type, value, connection=connection, prepared=prepared) - def is_hidden(self): "Should the related object be hidden?" return bool(self.related_name) and self.related_name[-1] == '+' diff --git a/django/db/models/lookups.py b/django/db/models/lookups.py index 62acfcb887..9f398b2b1a 100644 --- a/django/db/models/lookups.py +++ b/django/db/models/lookups.py @@ -16,6 +16,7 @@ from django.utils.six.moves import range class Lookup(object): lookup_name = None + prepare_rhs = True def __init__(self, lhs, rhs): self.lhs, self.rhs = lhs, rhs @@ -56,12 +57,14 @@ class Lookup(object): return sqls, sqls_params def get_prep_lookup(self): - return self.lhs.output_field.get_prep_lookup(self.lookup_name, self.rhs) + if hasattr(self.rhs, '_prepare'): + return self.rhs._prepare(self.lhs.output_field) + if self.prepare_rhs and hasattr(self.lhs.output_field, 'get_prep_value'): + return self.lhs.output_field.get_prep_value(self.rhs) + return self.rhs def get_db_prep_lookup(self, value, connection): - return ( - '%s', self.lhs.output_field.get_db_prep_lookup( - self.lookup_name, value, connection, prepared=True)) + return ('%s', [value]) def process_lhs(self, compiler, connection, lhs=None): lhs = lhs or self.lhs @@ -199,6 +202,7 @@ Field.register_lookup(Exact) class IExact(BuiltinLookup): lookup_name = 'iexact' + prepare_rhs = False def process_rhs(self, qn, connection): rhs, params = super(IExact, self).process_rhs(qn, connection) @@ -254,6 +258,13 @@ IntegerField.register_lookup(IntegerLessThan) class In(FieldGetDbPrepValueIterableMixin, BuiltinLookup): lookup_name = 'in' + def get_prep_lookup(self): + if hasattr(self.rhs, '_prepare'): + return self.rhs._prepare(self.lhs.output_field) + if hasattr(self.lhs.output_field, 'get_prep_value'): + return [self.lhs.output_field.get_prep_value(v) for v in self.rhs] + return self.rhs + def process_rhs(self, compiler, connection): db_rhs = getattr(self.rhs, '_db', None) if db_rhs is not None and db_rhs != connection.alias: @@ -335,6 +346,7 @@ class PatternLookup(BuiltinLookup): class Contains(PatternLookup): lookup_name = 'contains' + prepare_rhs = False def process_rhs(self, qn, connection): rhs, params = super(Contains, self).process_rhs(qn, connection) @@ -346,11 +358,13 @@ Field.register_lookup(Contains) class IContains(Contains): lookup_name = 'icontains' + prepare_rhs = False Field.register_lookup(IContains) class StartsWith(PatternLookup): lookup_name = 'startswith' + prepare_rhs = False def process_rhs(self, qn, connection): rhs, params = super(StartsWith, self).process_rhs(qn, connection) @@ -362,6 +376,7 @@ Field.register_lookup(StartsWith) class IStartsWith(PatternLookup): lookup_name = 'istartswith' + prepare_rhs = False def process_rhs(self, qn, connection): rhs, params = super(IStartsWith, self).process_rhs(qn, connection) @@ -373,6 +388,7 @@ Field.register_lookup(IStartsWith) class EndsWith(PatternLookup): lookup_name = 'endswith' + prepare_rhs = False def process_rhs(self, qn, connection): rhs, params = super(EndsWith, self).process_rhs(qn, connection) @@ -384,6 +400,7 @@ Field.register_lookup(EndsWith) class IEndsWith(PatternLookup): lookup_name = 'iendswith' + prepare_rhs = False def process_rhs(self, qn, connection): rhs, params = super(IEndsWith, self).process_rhs(qn, connection) @@ -396,6 +413,11 @@ Field.register_lookup(IEndsWith) class Range(FieldGetDbPrepValueIterableMixin, BuiltinLookup): lookup_name = 'range' + def get_prep_lookup(self): + if hasattr(self.rhs, '_prepare'): + return self.rhs._prepare(self.lhs.output_field) + return [self.lhs.output_field.get_prep_value(v) for v in self.rhs] + def get_rhs_op(self, connection, rhs): return "BETWEEN %s AND %s" % (rhs[0], rhs[1]) @@ -411,6 +433,7 @@ Field.register_lookup(Range) class IsNull(BuiltinLookup): lookup_name = 'isnull' + prepare_rhs = False def as_sql(self, compiler, connection): sql, params = compiler.compile(self.lhs) @@ -423,6 +446,7 @@ Field.register_lookup(IsNull) class Search(BuiltinLookup): lookup_name = 'search' + prepare_rhs = False def as_sql(self, compiler, connection): warnings.warn( @@ -438,6 +462,7 @@ Field.register_lookup(Search) class Regex(BuiltinLookup): lookup_name = 'regex' + prepare_rhs = False def as_sql(self, compiler, connection): if self.lookup_name in connection.operators: |
