summaryrefslogtreecommitdiff
path: root/django/db
diff options
context:
space:
mode:
Diffstat (limited to 'django/db')
-rw-r--r--django/db/backends/base/features.py3
-rw-r--r--django/db/backends/base/operations.py17
-rw-r--r--django/db/backends/oracle/operations.py2
-rw-r--r--django/db/backends/postgresql_psycopg2/base.py10
-rw-r--r--django/db/backends/postgresql_psycopg2/features.py1
-rw-r--r--django/db/backends/postgresql_psycopg2/operations.py28
-rw-r--r--django/db/models/fields/__init__.py6
-rw-r--r--django/db/models/lookups.py2
8 files changed, 53 insertions, 16 deletions
diff --git a/django/db/backends/base/features.py b/django/db/backends/base/features.py
index fe13827b77..0f6ee0efe3 100644
--- a/django/db/backends/base/features.py
+++ b/django/db/backends/base/features.py
@@ -59,6 +59,9 @@ class BaseDatabaseFeatures(object):
supports_subqueries_in_group_by = True
supports_bitwise_or = True
+ # Is there a true datatype for uuid?
+ has_native_uuid_field = False
+
# Is there a true datatype for timedeltas?
has_native_duration_field = False
diff --git a/django/db/backends/base/operations.py b/django/db/backends/base/operations.py
index c4e78e719e..24bcbb3d08 100644
--- a/django/db/backends/base/operations.py
+++ b/django/db/backends/base/operations.py
@@ -219,7 +219,7 @@ class BaseDatabaseOperations(object):
"""
return cursor.lastrowid
- def lookup_cast(self, lookup_type):
+ def lookup_cast(self, lookup_type, internal_type=None):
"""
Returns the string to use in a query when performing lookups
("contains", "like", etc). The resulting string should contain a '%s'
@@ -442,7 +442,7 @@ class BaseDatabaseOperations(object):
def value_to_db_date(self, value):
"""
- Transform a date value to an object compatible with what is expected
+ Transforms a date value to an object compatible with what is expected
by the backend driver for date columns.
"""
if value is None:
@@ -451,7 +451,7 @@ class BaseDatabaseOperations(object):
def value_to_db_datetime(self, value):
"""
- Transform a datetime value to an object compatible with what is expected
+ Transforms a datetime value to an object compatible with what is expected
by the backend driver for datetime columns.
"""
if value is None:
@@ -460,7 +460,7 @@ class BaseDatabaseOperations(object):
def value_to_db_time(self, value):
"""
- Transform a time value to an object compatible with what is expected
+ Transforms a time value to an object compatible with what is expected
by the backend driver for time columns.
"""
if value is None:
@@ -471,11 +471,18 @@ class BaseDatabaseOperations(object):
def value_to_db_decimal(self, value, max_digits, decimal_places):
"""
- Transform a decimal.Decimal value to an object compatible with what is
+ Transforms a decimal.Decimal value to an object compatible with what is
expected by the backend driver for decimal (numeric) columns.
"""
return utils.format_number(value, max_digits, decimal_places)
+ def value_to_db_ipaddress(self, value):
+ """
+ Transforms a string representation of an IP address into the expected
+ type for the backend driver.
+ """
+ return value
+
def year_lookup_bounds_for_date_field(self, value):
"""
Returns a two-elements list with the lower and upper bound to be used
diff --git a/django/db/backends/oracle/operations.py b/django/db/backends/oracle/operations.py
index f00fd3fbea..fe9c93ba90 100644
--- a/django/db/backends/oracle/operations.py
+++ b/django/db/backends/oracle/operations.py
@@ -246,7 +246,7 @@ WHEN (new.%(col_name)s IS NULL)
cursor.execute('SELECT "%s".currval FROM dual' % sq_name)
return cursor.fetchone()[0]
- def lookup_cast(self, lookup_type):
+ def lookup_cast(self, lookup_type, internal_type=None):
if lookup_type in ('iexact', 'icontains', 'istartswith', 'iendswith'):
return "UPPER(%s)"
return "%s"
diff --git a/django/db/backends/postgresql_psycopg2/base.py b/django/db/backends/postgresql_psycopg2/base.py
index 34b2870773..37433c3987 100644
--- a/django/db/backends/postgresql_psycopg2/base.py
+++ b/django/db/backends/postgresql_psycopg2/base.py
@@ -38,6 +38,16 @@ psycopg2.extensions.register_adapter(SafeBytes, psycopg2.extensions.QuotedString
psycopg2.extensions.register_adapter(SafeText, psycopg2.extensions.QuotedString)
psycopg2.extras.register_uuid()
+# Register support for inet[] manually so we don't have to handle the Inet()
+# object on load all the time.
+INETARRAY_OID = 1041
+INETARRAY = psycopg2.extensions.new_array_type(
+ (INETARRAY_OID,),
+ 'INETARRAY',
+ psycopg2.extensions.UNICODE,
+)
+psycopg2.extensions.register_type(INETARRAY)
+
class DatabaseWrapper(BaseDatabaseWrapper):
vendor = 'postgresql'
diff --git a/django/db/backends/postgresql_psycopg2/features.py b/django/db/backends/postgresql_psycopg2/features.py
index 64acd0570a..6bb6de1a96 100644
--- a/django/db/backends/postgresql_psycopg2/features.py
+++ b/django/db/backends/postgresql_psycopg2/features.py
@@ -6,6 +6,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
needs_datetime_string_cast = False
can_return_id_from_insert = True
has_real_datatype = True
+ has_native_uuid_field = True
has_native_duration_field = True
driver_supports_timedelta_args = True
can_defer_constraint_checks = True
diff --git a/django/db/backends/postgresql_psycopg2/operations.py b/django/db/backends/postgresql_psycopg2/operations.py
index 8e90a4020b..27b19db459 100644
--- a/django/db/backends/postgresql_psycopg2/operations.py
+++ b/django/db/backends/postgresql_psycopg2/operations.py
@@ -3,6 +3,8 @@ from __future__ import unicode_literals
from django.conf import settings
from django.db.backends.base.operations import BaseDatabaseOperations
+from psycopg2.extras import Inet
+
class DatabaseOperations(BaseDatabaseOperations):
def unification_cast_sql(self, output_field):
@@ -57,13 +59,16 @@ class DatabaseOperations(BaseDatabaseOperations):
def deferrable_sql(self):
return " DEFERRABLE INITIALLY DEFERRED"
- def lookup_cast(self, lookup_type):
+ def lookup_cast(self, lookup_type, internal_type=None):
lookup = '%s'
# Cast text lookups to text to allow things like filter(x__contains=4)
if lookup_type in ('iexact', 'contains', 'icontains', 'startswith',
'istartswith', 'endswith', 'iendswith', 'regex', 'iregex'):
- lookup = "%s::text"
+ if internal_type in ('IPAddressField', 'GenericIPAddressField'):
+ lookup = "HOST(%s)"
+ else:
+ lookup = "%s::text"
# Use UPPER(x) for case-insensitive lookups; it's faster.
if lookup_type in ('iexact', 'icontains', 'istartswith', 'iendswith'):
@@ -71,11 +76,6 @@ class DatabaseOperations(BaseDatabaseOperations):
return lookup
- def field_cast_sql(self, db_type, internal_type):
- if internal_type == "GenericIPAddressField" or internal_type == "IPAddressField":
- return 'HOST(%s)'
- return '%s'
-
def last_insert_id(self, cursor, table_name, pk_name):
# Use pg_get_serial_sequence to get the underlying sequence name
# from the table name and column name (available since PostgreSQL 8)
@@ -224,3 +224,17 @@ class DatabaseOperations(BaseDatabaseOperations):
def bulk_insert_sql(self, fields, num_values):
items_sql = "(%s)" % ", ".join(["%s"] * len(fields))
return "VALUES " + ", ".join([items_sql] * num_values)
+
+ def value_to_db_date(self, value):
+ return value
+
+ def value_to_db_datetime(self, value):
+ return value
+
+ def value_to_db_time(self, value):
+ return value
+
+ def value_to_db_ipaddress(self, value):
+ if value:
+ return Inet(value)
+ return None
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index 03c7eafac6..d5dfac733f 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -1983,7 +1983,7 @@ class GenericIPAddressField(Field):
def get_db_prep_value(self, value, connection, prepared=False):
if not prepared:
value = self.get_prep_value(value)
- return value or None
+ return connection.ops.value_to_db_ipaddress(value)
def get_prep_value(self, value):
value = super(GenericIPAddressField, self).get_prep_value(value)
@@ -2366,8 +2366,10 @@ class UUIDField(Field):
def get_internal_type(self):
return "UUIDField"
- def get_prep_value(self, value):
+ def get_db_prep_value(self, value, connection, prepared=False):
if isinstance(value, uuid.UUID):
+ if connection.features.has_native_uuid_field:
+ return value
return value.hex
if isinstance(value, six.string_types):
return value.replace('-', '')
diff --git a/django/db/models/lookups.py b/django/db/models/lookups.py
index d7423762f3..7610c0dde4 100644
--- a/django/db/models/lookups.py
+++ b/django/db/models/lookups.py
@@ -198,7 +198,7 @@ class BuiltinLookup(Lookup):
db_type = self.lhs.output_field.db_type(connection=connection)
lhs_sql = connection.ops.field_cast_sql(
db_type, field_internal_type) % lhs_sql
- lhs_sql = connection.ops.lookup_cast(self.lookup_name) % lhs_sql
+ lhs_sql = connection.ops.lookup_cast(self.lookup_name, field_internal_type) % lhs_sql
return lhs_sql, params
def as_sql(self, compiler, connection):