diff options
author | Marc Tamlyn <marc.tamlyn@gmail.com> | 2015-01-10 18:13:28 +0000 |
---|---|---|
committer | Tim Graham <timograham@gmail.com> | 2015-01-16 16:15:16 -0500 |
commit | 39d95fb6ada99c59d47fa0eae6d3128abafe2d58 (patch) | |
tree | f514f85027835d6504a80982184467c41da601c7 /django/db/backends/postgresql_psycopg2/operations.py | |
parent | a17724b791275578334bcdc66b3a8113eb86605e (diff) | |
download | django-39d95fb6ada99c59d47fa0eae6d3128abafe2d58.tar.gz |
Fixed #24092 -- Widened base field support for ArrayField.
Several issues resolved here, following from a report that a base_field
of GenericIpAddressField was failing.
We were using get_prep_value instead of get_db_prep_value in ArrayField
which was bypassing any extra modifications to the value being made in
the base field's get_db_prep_value. Changing this broke datetime
support, so the postgres backend has gained the relevant operation
methods to send dates/times/datetimes directly to the db backend instead
of casting them to strings. Similarly, a new database feature has been
added allowing the uuid to be passed directly to the backend, as we do
with timedeltas.
On the other side, psycopg2 expects an Inet() instance for IP address
fields, so we add a value_to_db_ipaddress method to wrap the strings on
postgres. We also have to manually add a database adapter to psycopg2,
as we do not wish to use the built in adapter which would turn
everything into Inet() instances.
Thanks to smclenithan for the report.
Diffstat (limited to 'django/db/backends/postgresql_psycopg2/operations.py')
-rw-r--r-- | django/db/backends/postgresql_psycopg2/operations.py | 28 |
1 files changed, 21 insertions, 7 deletions
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 |