Author: Alex
Date: 2009-07-17 10:57:43 -0500 (Fri, 17 Jul 2009)
New Revision: 11264
Modified:
django/branches/soc2009/multidb/django/db/models/base.py
django/branches/soc2009/multidb/django/db/models/fields/__init__.py
django/branches/soc2009/multidb/django/db/models/fields/files.py
django/branches/soc2009/multidb/django/db/models/fields/related.py
django/branches/soc2009/multidb/django/db/models/related.py
django/branches/soc2009/multidb/django/db/models/sql/subqueries.py
django/branches/soc2009/multidb/django/db/models/sql/where.py
django/branches/soc2009/multidb/django/forms/models.py
django/branches/soc2009/multidb/docs/howto/custom-model-fields.txt
django/branches/soc2009/multidb/tests/regressiontests/model_fields/tests.py
Log:
[soc2009/multidb] Added connection parameter to the get_db_prep_* family of
functions. This allows us to generate the lookup and save values for Fields in
a backend specific manner.
Modified: django/branches/soc2009/multidb/django/db/models/base.py
===================================================================
--- django/branches/soc2009/multidb/django/db/models/base.py 2009-07-17
12:36:29 UTC (rev 11263)
+++ django/branches/soc2009/multidb/django/db/models/base.py 2009-07-17
15:57:43 UTC (rev 11264)
@@ -18,6 +18,7 @@
from django.db import connections, transaction, DatabaseError, DEFAULT_DB_ALIAS
from django.db.models import signals
from django.db.models.loading import register_models, get_model
+from django.db.utils import call_with_connection
from django.utils.functional import curry
from django.utils.encoding import smart_str, force_unicode, smart_unicode
from django.conf import settings
@@ -483,9 +484,11 @@
if not pk_set:
if force_update:
raise ValueError("Cannot force an update in save()
with no primary key.")
- values = [(f, f.get_db_prep_save(raw and getattr(self,
f.attname) or f.pre_save(self, True))) for f in meta.local_fields if not
isinstance(f, AutoField)]
+ values = [(f, call_with_connection(f.get_db_prep_save, raw
and getattr(self, f.attname) or f.pre_save(self, True), connection=connection))
+ for f in meta.local_fields if not isinstance(f,
AutoField)]
else:
- values = [(f, f.get_db_prep_save(raw and getattr(self,
f.attname) or f.pre_save(self, True))) for f in meta.local_fields]
+ values = [(f, call_with_connection(f.get_db_prep_save, raw
and getattr(self, f.attname) or f.pre_save(self, True), connection=connection))
+ for f in meta.local_fields]
if meta.order_with_respect_to:
field = meta.order_with_respect_to
Modified: django/branches/soc2009/multidb/django/db/models/fields/__init__.py
===================================================================
--- django/branches/soc2009/multidb/django/db/models/fields/__init__.py
2009-07-17 12:36:29 UTC (rev 11263)
+++ django/branches/soc2009/multidb/django/db/models/fields/__init__.py
2009-07-17 15:57:43 UTC (rev 11264)
@@ -11,6 +11,7 @@
from django.db import connection
from django.db.models import signals
from django.db.models.query_utils import QueryWrapper
+from django.db.utils import call_with_connection
from django.dispatch import dispatcher
from django.conf import settings
from django import forms
@@ -178,7 +179,7 @@
"Returns field's value just before saving."
return getattr(model_instance, self.attname)
- def get_db_prep_value(self, value):
+ def get_db_prep_value(self, value, connection):
"""Returns field's value prepared for interacting with the database
backend.
@@ -187,11 +188,12 @@
"""
return value
- def get_db_prep_save(self, value):
+ def get_db_prep_save(self, value, connection):
"Returns field's value prepared for saving into a database."
- return self.get_db_prep_value(value)
+ return call_with_connection(self.get_db_prep_value, value,
+ connection=connection)
- def get_db_prep_lookup(self, lookup_type, value):
+ def get_db_prep_lookup(self, lookup_type, value, connection):
"Returns field's value prepared for database lookup."
if hasattr(value, 'as_sql') or hasattr(value, '_as_sql'):
# If the value has a relabel_aliases method, it will need to
@@ -208,9 +210,9 @@
if lookup_type in ('regex', 'iregex', 'month', 'day', 'week_day',
'search'):
return [value]
elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte'):
- return [self.get_db_prep_value(value)]
+ return [call_with_connection(self.get_db_prep_value, value,
connection=connection)]
elif lookup_type in ('range', 'in'):
- return [self.get_db_prep_value(v) for v in value]
+ return [call_with_connection(self.get_db_prep_value, v,
connection=connection) for v in value]
elif lookup_type in ('contains', 'icontains'):
return ["%%%s%%" % connection.ops.prep_for_like_query(value)]
elif lookup_type == 'iexact':
@@ -374,7 +376,7 @@
raise exceptions.ValidationError(
_("This value must be an integer."))
- def get_db_prep_value(self, value):
+ def get_db_prep_value(self, value, connection):
if value is None:
return None
return int(value)
@@ -417,14 +419,15 @@
raise exceptions.ValidationError(
_("This value must be either True or False."))
- def get_db_prep_lookup(self, lookup_type, value):
+ def get_db_prep_lookup(self, lookup_type, value, connection):
# 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_db_prep_lookup(lookup_type, value)
+ return call_with_connection(super(BooleanField,
self).get_db_prep_lookup,
+ lookup_type, value, connection=connection)
def validate(self, lookup_type, value):
if super(BooleanField, self).validate(lookup_type, value):
@@ -433,7 +436,7 @@
value = int(value)
bool(value)
- def get_db_prep_value(self, value):
+ def get_db_prep_value(self, value, connection):
if value is None:
return None
return bool(value)
@@ -536,14 +539,15 @@
setattr(cls, 'get_previous_by_%s' % self.name,
curry(cls._get_next_or_previous_by_FIELD, field=self,
is_next=False))
- def get_db_prep_lookup(self, lookup_type, value):
+ def get_db_prep_lookup(self, lookup_type, value, connection):
# For "__month", "__day", and "__week_day" lookups, convert the value
# to an int so the database backend always sees a consistent type.
if lookup_type in ('month', 'day', 'week_day'):
return [int(value)]
- return super(DateField, self).get_db_prep_lookup(lookup_type, value)
+ return call_with_connection(super(DateField, self).get_db_prep_lookup,
+ lookup_type, value, connection=connection)
- def get_db_prep_value(self, value):
+ def get_db_prep_value(self, value, connection):
# Casts dates into the format expected by the backend
return connection.ops.value_to_db_date(self.to_python(value))
@@ -615,7 +619,7 @@
raise exceptions.ValidationError(
_('Enter a valid date/time in YYYY-MM-DD
HH:MM[:ss[.uuuuuu]] format.'))
- def get_db_prep_value(self, value):
+ def get_db_prep_value(self, value, connection):
# Casts dates into the format expected by the backend
return connection.ops.value_to_db_datetime(self.to_python(value))
@@ -671,11 +675,11 @@
from django.db.backends import util
return util.format_number(value, self.max_digits, self.decimal_places)
- def get_db_prep_save(self, value):
+ def get_db_prep_save(self, value, connection):
return connection.ops.value_to_db_decimal(self.to_python(value),
self.max_digits, self.decimal_places)
- def get_db_prep_value(self, value):
+ def get_db_prep_value(self, value, connection):
return self.to_python(value)
def formfield(self, **kwargs):
@@ -719,7 +723,7 @@
class FloatField(Field):
empty_strings_allowed = False
- def get_db_prep_value(self, value):
+ def get_db_prep_value(self, value, connection):
if value is None:
return None
return float(value)
@@ -743,7 +747,7 @@
class IntegerField(Field):
empty_strings_allowed = False
- def get_db_prep_value(self, value):
+ def get_db_prep_value(self, value, connection):
if value is None:
return None
return int(value)
@@ -796,21 +800,22 @@
raise exceptions.ValidationError(
_("This value must be either None, True or False."))
- def get_db_prep_lookup(self, lookup_type, value):
+ def get_db_prep_lookup(self, lookup_type, value, connection):
# 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_db_prep_lookup(lookup_type,
value)
+ return call_with_connection(super(NullBooleanField,
self).get_db_prep_lookup,
+ lookup_type, value, connection=connection)
def validate(self, lookup_type, value):
if value in ('1', '0'):
value = int(value)
bool(value)
- def get_db_prep_value(self, value):
+ def get_db_prep_value(self, value, connection):
if value is None:
return None
return bool(value)
@@ -926,7 +931,7 @@
else:
return super(TimeField, self).pre_save(model_instance, add)
- def get_db_prep_value(self, value):
+ def get_db_prep_value(self, value, connection):
# Casts times into the format expected by the backend
return connection.ops.value_to_db_time(self.to_python(value))
Modified: django/branches/soc2009/multidb/django/db/models/fields/files.py
===================================================================
--- django/branches/soc2009/multidb/django/db/models/fields/files.py
2009-07-17 12:36:29 UTC (rev 11263)
+++ django/branches/soc2009/multidb/django/db/models/fields/files.py
2009-07-17 15:57:43 UTC (rev 11264)
@@ -10,6 +10,7 @@
from django.core.files.uploadedfile import UploadedFile
from django.utils.functional import curry
from django.db.models import signals
+from django.db.utils import call_with_connection
from django.utils.encoding import force_unicode, smart_str
from django.utils.translation import ugettext_lazy, ugettext as _
from django import forms
@@ -232,12 +233,13 @@
def get_internal_type(self):
return "FileField"
- def get_db_prep_lookup(self, lookup_type, value):
+ def get_db_prep_lookup(self, lookup_type, value, connection):
if hasattr(value, 'name'):
value = value.name
- return super(FileField, self).get_db_prep_lookup(lookup_type, value)
+ return call_with_connection(super(FileField, self).get_db_prep_lookup,
+ lookup_type, value, connection=connection)
- def get_db_prep_value(self, value):
+ def get_db_prep_value(self, value, connection):
"Returns field's value prepared for saving into a database."
# Need to convert File objects provided via a form to unicode for
database insertion
if value is None:
Modified: django/branches/soc2009/multidb/django/db/models/fields/related.py
===================================================================
--- django/branches/soc2009/multidb/django/db/models/fields/related.py
2009-07-17 12:36:29 UTC (rev 11263)
+++ django/branches/soc2009/multidb/django/db/models/fields/related.py
2009-07-17 15:57:43 UTC (rev 11264)
@@ -117,7 +117,7 @@
if not cls._meta.abstract:
self.contribute_to_related_class(other, self.related)
- def get_db_prep_lookup(self, lookup_type, value):
+ def get_db_prep_lookup(self, lookup_type, value, connection):
# If we are doing a lookup on a Related Field, we must be
# comparing object instances. The value should be the PK of value,
# not value itself.
@@ -137,7 +137,8 @@
if field:
if lookup_type in ('range', 'in'):
v = [v]
- v = field.get_db_prep_lookup(lookup_type, v)
+ v = call_with_connection(field.get_db_prep_lookup,
+ lookup_type, v, connection=connection)
if isinstance(v, list):
v = v[0]
return v
@@ -720,11 +721,12 @@
return getattr(field_default, self.rel.get_related_field().attname)
return field_default
- def get_db_prep_save(self, value):
+ def get_db_prep_save(self, value, connection):
if value == '' or value == None:
return None
else:
- return self.rel.get_related_field().get_db_prep_save(value)
+ return
call_with_connection(self.rel.get_related_field().get_db_prep_save,
+ value, connection=connection)
def value_to_string(self, obj):
if not obj:
Modified: django/branches/soc2009/multidb/django/db/models/related.py
===================================================================
--- django/branches/soc2009/multidb/django/db/models/related.py 2009-07-17
12:36:29 UTC (rev 11263)
+++ django/branches/soc2009/multidb/django/db/models/related.py 2009-07-17
15:57:43 UTC (rev 11264)
@@ -18,7 +18,7 @@
self.name = '%s:%s' % (self.opts.app_label, self.opts.module_name)
self.var_name = self.opts.object_name.lower()
- def get_db_prep_lookup(self, lookup_type, value):
+ def get_db_prep_lookup(self, lookup_type, value, connection):
# Defer to the actual field definition for db prep
return self.field.get_db_prep_lookup(lookup_type, value)
Modified: django/branches/soc2009/multidb/django/db/models/sql/subqueries.py
===================================================================
--- django/branches/soc2009/multidb/django/db/models/sql/subqueries.py
2009-07-17 12:36:29 UTC (rev 11263)
+++ django/branches/soc2009/multidb/django/db/models/sql/subqueries.py
2009-07-17 15:57:43 UTC (rev 11264)
@@ -8,6 +8,7 @@
from django.db.models.sql.expressions import SQLEvaluator
from django.db.models.sql.query import Query
from django.db.models.sql.where import AND, Constraint
+from django.db.utils import call_with_connection
__all__ = ['DeleteQuery', 'UpdateQuery', 'InsertQuery', 'DateQuery',
'AggregateQuery']
@@ -243,7 +244,8 @@
if hasattr(val, 'prepare_database_save'):
val = val.prepare_database_save(field)
else:
- val = field.get_db_prep_save(val)
+ val = call_with_connection(field.get_db_prep_save,
+ val, connection=self.connection)
# Getting the placeholder for the field.
if hasattr(field, 'get_placeholder'):
Modified: django/branches/soc2009/multidb/django/db/models/sql/where.py
===================================================================
--- django/branches/soc2009/multidb/django/db/models/sql/where.py
2009-07-17 12:36:29 UTC (rev 11263)
+++ django/branches/soc2009/multidb/django/db/models/sql/where.py
2009-07-17 15:57:43 UTC (rev 11264)
@@ -143,7 +143,8 @@
except EmptyShortCircuit:
raise EmptyResultSet
else:
- params = Field().get_db_prep_lookup(lookup_type, params_or_value)
+ params = call_with_connection(Field().get_db_prep_lookup,
+ lookup_type, params_or_value, connection=connection)
if isinstance(lvalue, tuple):
# A direct database column lookup.
field_sql = self.sql_for_columns(lvalue, qn, connection)
@@ -266,13 +267,15 @@
from django.db.models.base import ObjectDoesNotExist
try:
if self.field:
- params = self.field.get_db_prep_lookup(lookup_type, value)
+ params = call_with_connection(self.field.get_db_prep_lookup,
+ lookup_type, value, connection=connection)
db_type = call_with_connection(self.field.db_type,
connection=connection)
else:
# This branch is used at times when we add a comparison to NULL
# (we don't really want to waste time looking up the associated
# field object at the calling location).
- params = Field().get_db_prep_lookup(lookup_type, value)
+ params = call_with_connection(Field().get_db_prep_lookup,
+ lookup_type, value, connection=connection)
db_type = None
except ObjectDoesNotExist:
raise EmptyShortCircuit
Modified: django/branches/soc2009/multidb/django/forms/models.py
===================================================================
--- django/branches/soc2009/multidb/django/forms/models.py 2009-07-17
12:36:29 UTC (rev 11263)
+++ django/branches/soc2009/multidb/django/forms/models.py 2009-07-17
15:57:43 UTC (rev 11264)
@@ -3,6 +3,7 @@
and database field objects.
"""
+from django.db.utils import call_with_connection
from django.utils.encoding import smart_unicode, force_unicode
from django.utils.datastructures import SortedDict
from django.utils.text import get_text_list, capfirst
@@ -474,7 +475,8 @@
pk_key = "%s-%s" % (self.add_prefix(i), self.model._meta.pk.name)
pk = self.data[pk_key]
pk_field = self.model._meta.pk
- pk = pk_field.get_db_prep_lookup('exact', pk)
+ pk = call_with_connection(pk_field.get_db_prep_lookup, 'exact', pk,
+ connection=self.get_queryset().query.connection)
if isinstance(pk, list):
pk = pk[0]
kwargs['instance'] = self._existing_object(pk)
Modified: django/branches/soc2009/multidb/docs/howto/custom-model-fields.txt
===================================================================
--- django/branches/soc2009/multidb/docs/howto/custom-model-fields.txt
2009-07-17 12:36:29 UTC (rev 11263)
+++ django/branches/soc2009/multidb/docs/howto/custom-model-fields.txt
2009-07-17 15:57:43 UTC (rev 11264)
@@ -399,24 +399,27 @@
Converting Python objects to database values
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. method:: get_db_prep_value(self, value)
+.. method:: get_db_prep_value(self, value, connection)
This is the reverse of :meth:`to_python` when working with the database
backends
(as opposed to serialization). The ``value`` parameter is the current value of
the model's attribute (a field has no reference to its containing model, so it
cannot retrieve the value itself), and the method should return data in a
format
-that can be used as a parameter in a query for the database backend.
+that can be used as a parameter in a query for the database backend. The
+specific connection that will be used for the query is passed as the
+``connection`` parameter, this allows you to generate the value in a backend
+specific mannner if necessary.
For example::
class HandField(models.Field):
# ...
- def get_db_prep_value(self, value):
+ def get_db_prep_value(self, value, connection):
return ''.join([''.join(l) for l in (value.north,
value.east, value.south, value.west)])
-.. method:: get_db_prep_save(self, value)
+.. method:: get_db_prep_save(self, value, connection)
Same as the above, but called when the Field value must be *saved* to the
database. As the default implementation just calls ``get_db_prep_value``, you
@@ -450,7 +453,7 @@
Preparing values for use in database lookups
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. method:: get_db_prep_lookup(self, lookup_type, value)
+.. method:: get_db_prep_lookup(self, lookup_type, value, connection)
Prepares the ``value`` for passing to the database when used in a lookup (a
``WHERE`` constraint in SQL). The ``lookup_type`` will be one of the valid
Modified:
django/branches/soc2009/multidb/tests/regressiontests/model_fields/tests.py
===================================================================
--- django/branches/soc2009/multidb/tests/regressiontests/model_fields/tests.py
2009-07-17 12:36:29 UTC (rev 11263)
+++ django/branches/soc2009/multidb/tests/regressiontests/model_fields/tests.py
2009-07-17 15:57:43 UTC (rev 11264)
@@ -44,8 +44,9 @@
self.assertEqual(f._format(None), None)
def test_get_db_prep_lookup(self):
+ from django.db import connection
f = models.DecimalField(max_digits=5, decimal_places=1)
- self.assertEqual(f.get_db_prep_lookup('exact', None), [None])
+ self.assertEqual(f.get_db_prep_lookup('exact', None, connection),
[None])
def test_filter_with_strings(self):
"""
@@ -98,13 +99,14 @@
class BooleanFieldTests(unittest.TestCase):
def _test_get_db_prep_lookup(self, f):
- self.assertEqual(f.get_db_prep_lookup('exact', True), [True])
- self.assertEqual(f.get_db_prep_lookup('exact', '1'), [True])
- self.assertEqual(f.get_db_prep_lookup('exact', 1), [True])
- self.assertEqual(f.get_db_prep_lookup('exact', False), [False])
- self.assertEqual(f.get_db_prep_lookup('exact', '0'), [False])
- self.assertEqual(f.get_db_prep_lookup('exact', 0), [False])
- self.assertEqual(f.get_db_prep_lookup('exact', None), [None])
+ from django.db import connection
+ self.assertEqual(f.get_db_prep_lookup('exact', True, connection),
[True])
+ self.assertEqual(f.get_db_prep_lookup('exact', '1', connection),
[True])
+ self.assertEqual(f.get_db_prep_lookup('exact', 1, connection), [True])
+ self.assertEqual(f.get_db_prep_lookup('exact', False, connection),
[False])
+ self.assertEqual(f.get_db_prep_lookup('exact', '0', connection),
[False])
+ self.assertEqual(f.get_db_prep_lookup('exact', 0, connection), [False])
+ self.assertEqual(f.get_db_prep_lookup('exact', None, connection),
[None])
def test_booleanfield_get_db_prep_lookup(self):
self._test_get_db_prep_lookup(models.BooleanField())
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---