1
0
mirror of https://github.com/django/django.git synced 2025-07-05 10:19:20 +00:00

[soc2009/multidb] Switched from using an ugly hacky wrapper to a Metaclass for maitaing backwards compatibility in the get_db_prep_* and db_type methods. Thanks to Jacob for the good idea.

git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/multidb@11375 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Alex Gaynor 2009-08-01 05:26:02 +00:00
parent 7cf6fd8d61
commit 3cd611b89c
13 changed files with 84 additions and 63 deletions

View File

@ -2,7 +2,6 @@ from optparse import make_option
from django.core.management.base import LabelCommand from django.core.management.base import LabelCommand
from django.db import connections, transaction, models, DEFAULT_DB_ALIAS from django.db import connections, transaction, models, DEFAULT_DB_ALIAS
from django.db.utils import call_with_connection
class Command(LabelCommand): class Command(LabelCommand):
help = "Creates the table needed to use the SQL cache backend." help = "Creates the table needed to use the SQL cache backend."
@ -31,7 +30,7 @@ class Command(LabelCommand):
index_output = [] index_output = []
qn = connection.ops.quote_name qn = connection.ops.quote_name
for f in fields: for f in fields:
field_output = [qn(f.name), call_with_connection(f.db_type, connection=connection)] field_output = [qn(f.name), f.db_type(connection=connection)]
field_output.append("%sNULL" % (not f.null and "NOT " or "")) field_output.append("%sNULL" % (not f.null and "NOT " or ""))
if f.primary_key: if f.primary_key:
field_output.append("PRIMARY KEY") field_output.append("PRIMARY KEY")

View File

@ -116,7 +116,7 @@ def sql_delete(app, style, connection):
def sql_reset(app, style, connection): def sql_reset(app, style, connection):
"Returns a list of the DROP TABLE SQL, then the CREATE TABLE SQL, for the given module." "Returns a list of the DROP TABLE SQL, then the CREATE TABLE SQL, for the given module."
return sql_delete(app, style) + sql_all(app, style) return sql_delete(app, style, connection) + sql_all(app, style, connection)
def sql_flush(style, connection, only_django=False): def sql_flush(style, connection, only_django=False):
""" """

View File

@ -8,7 +8,6 @@ except NameError:
from django.conf import settings from django.conf import settings
from django.core.management import call_command from django.core.management import call_command
from django.db.utils import call_with_connection
# The prefix to put on the default database name when creating # The prefix to put on the default database name when creating
# the test database. # the test database.
@ -48,7 +47,7 @@ class BaseDatabaseCreation(object):
pending_references = {} pending_references = {}
qn = self.connection.ops.quote_name qn = self.connection.ops.quote_name
for f in opts.local_fields: for f in opts.local_fields:
col_type = call_with_connection(f.db_type, connection=self.connection) col_type = f.db_type(connection=self.connection)
tablespace = f.db_tablespace or opts.db_tablespace tablespace = f.db_tablespace or opts.db_tablespace
if col_type is None: if col_type is None:
# Skip ManyToManyFields, because they're not represented as # Skip ManyToManyFields, because they're not represented as
@ -76,7 +75,7 @@ class BaseDatabaseCreation(object):
table_output.append(' '.join(field_output)) table_output.append(' '.join(field_output))
if opts.order_with_respect_to: if opts.order_with_respect_to:
table_output.append(style.SQL_FIELD(qn('_order')) + ' ' + \ table_output.append(style.SQL_FIELD(qn('_order')) + ' ' + \
style.SQL_COLTYPE(models.IntegerField().db_type(self.connection))) style.SQL_COLTYPE(models.IntegerField().db_type(connection=self.connection)))
for field_constraints in opts.unique_together: for field_constraints in opts.unique_together:
table_output.append(style.SQL_KEYWORD('UNIQUE') + ' (%s)' % \ table_output.append(style.SQL_KEYWORD('UNIQUE') + ' (%s)' % \
", ".join([style.SQL_FIELD(qn(opts.get_field(f).column)) for f in field_constraints])) ", ".join([style.SQL_FIELD(qn(opts.get_field(f).column)) for f in field_constraints]))
@ -174,7 +173,7 @@ class BaseDatabaseCreation(object):
style.SQL_TABLE(qn(f.m2m_db_table())) + ' ('] style.SQL_TABLE(qn(f.m2m_db_table())) + ' (']
table_output.append(' %s %s %s%s,' % table_output.append(' %s %s %s%s,' %
(style.SQL_FIELD(qn('id')), (style.SQL_FIELD(qn('id')),
style.SQL_COLTYPE(models.AutoField(primary_key=True).db_type(self.connection)), style.SQL_COLTYPE(models.AutoField(primary_key=True).db_type(connection=self.connection)),
style.SQL_KEYWORD('NOT NULL PRIMARY KEY'), style.SQL_KEYWORD('NOT NULL PRIMARY KEY'),
tablespace_sql)) tablespace_sql))
@ -218,14 +217,14 @@ class BaseDatabaseCreation(object):
table_output = [ table_output = [
' %s %s %s %s (%s)%s,' % ' %s %s %s %s (%s)%s,' %
(style.SQL_FIELD(qn(field.m2m_column_name())), (style.SQL_FIELD(qn(field.m2m_column_name())),
style.SQL_COLTYPE(models.ForeignKey(model).db_type(self.connection)), style.SQL_COLTYPE(models.ForeignKey(model).db_type(connection=self.connection)),
style.SQL_KEYWORD('NOT NULL REFERENCES'), style.SQL_KEYWORD('NOT NULL REFERENCES'),
style.SQL_TABLE(qn(opts.db_table)), style.SQL_TABLE(qn(opts.db_table)),
style.SQL_FIELD(qn(opts.pk.column)), style.SQL_FIELD(qn(opts.pk.column)),
self.connection.ops.deferrable_sql()), self.connection.ops.deferrable_sql()),
' %s %s %s %s (%s)%s,' % ' %s %s %s %s (%s)%s,' %
(style.SQL_FIELD(qn(field.m2m_reverse_name())), (style.SQL_FIELD(qn(field.m2m_reverse_name())),
style.SQL_COLTYPE(models.ForeignKey(field.rel.to).db_type(self.connection)), style.SQL_COLTYPE(models.ForeignKey(field.rel.to).db_type(connection=self.connection)),
style.SQL_KEYWORD('NOT NULL REFERENCES'), style.SQL_KEYWORD('NOT NULL REFERENCES'),
style.SQL_TABLE(qn(field.rel.to._meta.db_table)), style.SQL_TABLE(qn(field.rel.to._meta.db_table)),
style.SQL_FIELD(qn(field.rel.to._meta.pk.column)), style.SQL_FIELD(qn(field.rel.to._meta.pk.column)),

View File

@ -18,7 +18,6 @@ from django.db.models.options import Options
from django.db import connections, transaction, DatabaseError, DEFAULT_DB_ALIAS from django.db import connections, transaction, DatabaseError, DEFAULT_DB_ALIAS
from django.db.models import signals from django.db.models import signals
from django.db.models.loading import register_models, get_model 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.functional import curry
from django.utils.encoding import smart_str, force_unicode, smart_unicode from django.utils.encoding import smart_str, force_unicode, smart_unicode
from django.conf import settings from django.conf import settings
@ -484,10 +483,10 @@ class Model(object):
if not pk_set: if not pk_set:
if force_update: if force_update:
raise ValueError("Cannot force an update in save() with no primary key.") raise ValueError("Cannot force an update in save() with no primary key.")
values = [(f, call_with_connection(f.get_db_prep_save, raw and getattr(self, f.attname) or f.pre_save(self, True), connection=connection)) values = [(f, 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)] for f in meta.local_fields if not isinstance(f, AutoField)]
else: else:
values = [(f, call_with_connection(f.get_db_prep_save, raw and getattr(self, f.attname) or f.pre_save(self, True), connection=connection)) values = [(f, 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] for f in meta.local_fields]
if meta.order_with_respect_to: if meta.order_with_respect_to:

View File

@ -10,8 +10,8 @@ except ImportError:
from django.db import connection from django.db import connection
from django.db.models import signals from django.db.models import signals
from django.db.models.fields.subclassing import LegacyConnection
from django.db.models.query_utils import QueryWrapper from django.db.models.query_utils import QueryWrapper
from django.db.utils import call_with_connection
from django.dispatch import dispatcher from django.dispatch import dispatcher
from django.conf import settings from django.conf import settings
from django import forms from django import forms
@ -50,6 +50,7 @@ class FieldDoesNotExist(Exception):
# getattr(obj, opts.pk.attname) # getattr(obj, opts.pk.attname)
class Field(object): class Field(object):
__metaclass__ = LegacyConnection
# Designates whether empty strings fundamentally are allowed at the # Designates whether empty strings fundamentally are allowed at the
# database level. # database level.
empty_strings_allowed = True empty_strings_allowed = True
@ -190,8 +191,7 @@ class Field(object):
def get_db_prep_save(self, value, connection): def get_db_prep_save(self, value, connection):
"Returns field's value prepared for saving into a database." "Returns field's value prepared for saving into a database."
return call_with_connection(self.get_db_prep_value, value, return self.get_db_prep_value(value, connection=connection)
connection=connection)
def get_db_prep_lookup(self, lookup_type, value, connection): def get_db_prep_lookup(self, lookup_type, value, connection):
"Returns field's value prepared for database lookup." "Returns field's value prepared for database lookup."
@ -210,9 +210,9 @@ class Field(object):
if lookup_type in ('regex', 'iregex', 'month', 'day', 'week_day', 'search'): if lookup_type in ('regex', 'iregex', 'month', 'day', 'week_day', 'search'):
return [value] return [value]
elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte'): elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte'):
return [call_with_connection(self.get_db_prep_value, value, connection=connection)] return [self.get_db_prep_value(value, connection=connection)]
elif lookup_type in ('range', 'in'): elif lookup_type in ('range', 'in'):
return [call_with_connection(self.get_db_prep_value, v, connection=connection) for v in value] return [self.get_db_prep_value(v, connection=connection) for v in value]
elif lookup_type in ('contains', 'icontains'): elif lookup_type in ('contains', 'icontains'):
return ["%%%s%%" % connection.ops.prep_for_like_query(value)] return ["%%%s%%" % connection.ops.prep_for_like_query(value)]
elif lookup_type == 'iexact': elif lookup_type == 'iexact':
@ -426,8 +426,8 @@ class BooleanField(Field):
# constructing the list. # constructing the list.
if value in ('1', '0'): if value in ('1', '0'):
value = bool(int(value)) value = bool(int(value))
return call_with_connection(super(BooleanField, self).get_db_prep_lookup, return super(BooleanField, self).get_db_prep_lookup(lookup_type, value,
lookup_type, value, connection=connection) connection=connection)
def validate(self, lookup_type, value): def validate(self, lookup_type, value):
if super(BooleanField, self).validate(lookup_type, value): if super(BooleanField, self).validate(lookup_type, value):
@ -544,8 +544,8 @@ class DateField(Field):
# to an int so the database backend always sees a consistent type. # to an int so the database backend always sees a consistent type.
if lookup_type in ('month', 'day', 'week_day'): if lookup_type in ('month', 'day', 'week_day'):
return [int(value)] return [int(value)]
return call_with_connection(super(DateField, self).get_db_prep_lookup, return super(DateField, self).get_db_prep_lookup(lookup_type, value,
lookup_type, value, connection=connection) connection=connection)
def get_db_prep_value(self, value, connection): def get_db_prep_value(self, value, connection):
# Casts dates into the format expected by the backend # Casts dates into the format expected by the backend
@ -807,8 +807,8 @@ class NullBooleanField(Field):
# constructing the list. # constructing the list.
if value in ('1', '0'): if value in ('1', '0'):
value = bool(int(value)) value = bool(int(value))
return call_with_connection(super(NullBooleanField, self).get_db_prep_lookup, return super(NullBooleanField, self).get_db_prep_lookup(lookup_type,
lookup_type, value, connection=connection) value, connection=connection)
def validate(self, lookup_type, value): def validate(self, lookup_type, value):
if value in ('1', '0'): if value in ('1', '0'):

View File

@ -10,7 +10,6 @@ from django.core.files.images import ImageFile, get_image_dimensions
from django.core.files.uploadedfile import UploadedFile from django.core.files.uploadedfile import UploadedFile
from django.utils.functional import curry from django.utils.functional import curry
from django.db.models import signals 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.encoding import force_unicode, smart_str
from django.utils.translation import ugettext_lazy, ugettext as _ from django.utils.translation import ugettext_lazy, ugettext as _
from django import forms from django import forms
@ -236,8 +235,8 @@ class FileField(Field):
def get_db_prep_lookup(self, lookup_type, value, connection): def get_db_prep_lookup(self, lookup_type, value, connection):
if hasattr(value, 'name'): if hasattr(value, 'name'):
value = value.name value = value.name
return call_with_connection(super(FileField, self).get_db_prep_lookup, return super(FileField, self).get_db_prep_lookup(lookup_type, value,
lookup_type, value, connection=connection) connection=connection)
def get_db_prep_value(self, value, connection): def get_db_prep_value(self, value, connection):
"Returns field's value prepared for saving into a database." "Returns field's value prepared for saving into a database."

View File

@ -5,7 +5,6 @@ from django.db.models.fields import AutoField, Field, IntegerField, PositiveInte
from django.db.models.related import RelatedObject from django.db.models.related import RelatedObject
from django.db.models.query import QuerySet from django.db.models.query import QuerySet
from django.db.models.query_utils import QueryWrapper from django.db.models.query_utils import QueryWrapper
from django.db.utils import call_with_connection
from django.utils.encoding import smart_unicode from django.utils.encoding import smart_unicode
from django.utils.translation import ugettext_lazy, string_concat, ungettext, ugettext as _ from django.utils.translation import ugettext_lazy, string_concat, ungettext, ugettext as _
from django.utils.functional import curry from django.utils.functional import curry
@ -137,8 +136,7 @@ class RelatedField(object):
if field: if field:
if lookup_type in ('range', 'in'): if lookup_type in ('range', 'in'):
v = [v] v = [v]
v = call_with_connection(field.get_db_prep_lookup, v = field.get_db_prep_lookup(lookup_type, v, connection=connection)
lookup_type, v, connection=connection)
if isinstance(v, list): if isinstance(v, list):
v = v[0] v = v[0]
return v return v
@ -725,8 +723,8 @@ class ForeignKey(RelatedField, Field):
if value == '' or value == None: if value == '' or value == None:
return None return None
else: else:
return call_with_connection(self.rel.get_related_field().get_db_prep_save, return self.rel.get_related_field().get_db_prep_save(value,
value, connection=connection) connection=connection)
def value_to_string(self, obj): def value_to_string(self, obj):
if not obj: if not obj:
@ -774,8 +772,8 @@ class ForeignKey(RelatedField, Field):
(not connection.features.related_fields_match_type and (not connection.features.related_fields_match_type and
isinstance(rel_field, (PositiveIntegerField, isinstance(rel_field, (PositiveIntegerField,
PositiveSmallIntegerField)))): PositiveSmallIntegerField)))):
return IntegerField().db_type(connection) return IntegerField().db_type(connection=connection)
return call_with_connection(rel_field.db_type, connection=connection) return rel_field.db_type(connection=connection)
class OneToOneField(ForeignKey): class OneToOneField(ForeignKey):
""" """

View File

@ -1,11 +1,48 @@
""" """
Convenience routines for creating non-trivial Field subclasses. Convenience routines for creating non-trivial Field subclasses, as well as
backwards compatibility utilities.
Add SubfieldBase as the __metaclass__ for your Field subclass, implement Add SubfieldBase as the __metaclass__ for your Field subclass, implement
to_python() and the other necessary methods and everything will work seamlessly. to_python() and the other necessary methods and everything will work seamlessly.
""" """
class SubfieldBase(type): from inspect import getargspec
from warnings import warn
def call_with_connection(func):
arg_names, varargs, varkwargs, defaults = getargspec(func)
takes_connection = 'connection' in arg_names or varkwargs
if not takes_connection:
warn("A Field class who's %s method doesn't take connection has been "
"defined, please add a connection argument" % func.__name__,
PendingDeprecationWarning, depth=2)
def inner(*args, **kwargs):
if 'connection' not in kwargs:
from django.db import connection
kwargs['connection'] = connection
warn("%s has been called without providing a connection argument, "
"please provide one" % func.__name__, PendingDeprecationWarning,
depth=1)
if takes_connection:
return func(*args, **kwargs)
if 'connection' in kwargs:
del kwargs['connection']
return func(*args, **kwargs)
return inner
class LegacyConnection(type):
"""
A metaclass to normalize arguments give to the get_db_prep_* and db_type
methods on fields.
"""
def __new__(cls, names, bases, attrs):
new_cls = super(LegacyConnection, cls).__new__(cls, names, bases, attrs)
for attr in ('db_type', 'get_db_prep_save', 'get_db_prep_lookup',
'get_db_prep_value'):
setattr(new_cls, attr, call_with_connection(getattr(new_cls, attr)))
return new_cls
class SubfieldBase(LegacyConnection):
""" """
A metaclass for custom Field subclasses. This ensures the model's attribute A metaclass for custom Field subclasses. This ensures the model's attribute
has the descriptor protocol attached to it. has the descriptor protocol attached to it.

View File

@ -8,7 +8,6 @@ from django.db.models.sql.datastructures import Date
from django.db.models.sql.expressions import SQLEvaluator from django.db.models.sql.expressions import SQLEvaluator
from django.db.models.sql.query import Query from django.db.models.sql.query import Query
from django.db.models.sql.where import AND, Constraint from django.db.models.sql.where import AND, Constraint
from django.db.utils import call_with_connection
__all__ = ['DeleteQuery', 'UpdateQuery', 'InsertQuery', 'DateQuery', __all__ = ['DeleteQuery', 'UpdateQuery', 'InsertQuery', 'DateQuery',
'AggregateQuery'] 'AggregateQuery']
@ -244,8 +243,7 @@ class UpdateQuery(Query):
if hasattr(val, 'prepare_database_save'): if hasattr(val, 'prepare_database_save'):
val = val.prepare_database_save(field) val = val.prepare_database_save(field)
else: else:
val = call_with_connection(field.get_db_prep_save, val = field.get_db_prep_save(val, connection=self.connection)
val, connection=self.connection)
# Getting the placeholder for the field. # Getting the placeholder for the field.
if hasattr(field, 'get_placeholder'): if hasattr(field, 'get_placeholder'):

View File

@ -6,7 +6,6 @@ import datetime
from django.utils import tree from django.utils import tree
from django.db.models.fields import Field from django.db.models.fields import Field
from django.db.models.query_utils import QueryWrapper from django.db.models.query_utils import QueryWrapper
from django.db.utils import call_with_connection
from datastructures import EmptyResultSet, FullResultSet from datastructures import EmptyResultSet, FullResultSet
# Connection types # Connection types
@ -143,8 +142,8 @@ class WhereNode(tree.Node):
except EmptyShortCircuit: except EmptyShortCircuit:
raise EmptyResultSet raise EmptyResultSet
else: else:
params = call_with_connection(Field().get_db_prep_lookup, params = Field().get_db_prep_lookup(lookup_type, params_or_value,
lookup_type, params_or_value, connection=connection) connection=connection)
if isinstance(lvalue, tuple): if isinstance(lvalue, tuple):
# A direct database column lookup. # A direct database column lookup.
field_sql = self.sql_for_columns(lvalue, qn, connection) field_sql = self.sql_for_columns(lvalue, qn, connection)
@ -267,15 +266,15 @@ class Constraint(object):
from django.db.models.base import ObjectDoesNotExist from django.db.models.base import ObjectDoesNotExist
try: try:
if self.field: if self.field:
params = call_with_connection(self.field.get_db_prep_lookup, params = self.field.get_db_prep_lookup(lookup_type, value,
lookup_type, value, connection=connection) connection=connection)
db_type = call_with_connection(self.field.db_type, connection=connection) db_type = self.field.db_type(connection=connection)
else: else:
# This branch is used at times when we add a comparison to NULL # 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 # (we don't really want to waste time looking up the associated
# field object at the calling location). # field object at the calling location).
params = call_with_connection(Field().get_db_prep_lookup, params = Field().get_db_prep_lookup(lookup_type, value,
lookup_type, value, connection=connection) connection=connection)
db_type = None db_type = None
except ObjectDoesNotExist: except ObjectDoesNotExist:
raise EmptyShortCircuit raise EmptyShortCircuit

View File

@ -32,12 +32,6 @@ def load_backend(backend_name):
else: else:
raise # If there's some other error, this must be an error in Django itself. raise # If there's some other error, this must be an error in Django itself.
def call_with_connection(func, *args, **kwargs):
arg_names, varargs, varkwargs, defaults = inspect.getargspec(func)
if 'connection' not in arg_names and varkwargs is None:
del kwargs['connection']
return func(*args, **kwargs)
class ConnectionHandler(object): class ConnectionHandler(object):
def __init__(self, databases): def __init__(self, databases):

View File

@ -3,7 +3,6 @@ Helper functions for creating Form classes from Django models
and database field objects. and database field objects.
""" """
from django.db.utils import call_with_connection
from django.utils.encoding import smart_unicode, force_unicode from django.utils.encoding import smart_unicode, force_unicode
from django.utils.datastructures import SortedDict from django.utils.datastructures import SortedDict
from django.utils.text import get_text_list, capfirst from django.utils.text import get_text_list, capfirst
@ -475,7 +474,7 @@ class BaseModelFormSet(BaseFormSet):
pk_key = "%s-%s" % (self.add_prefix(i), self.model._meta.pk.name) pk_key = "%s-%s" % (self.add_prefix(i), self.model._meta.pk.name)
pk = self.data[pk_key] pk = self.data[pk_key]
pk_field = self.model._meta.pk pk_field = self.model._meta.pk
pk = call_with_connection(pk_field.get_db_prep_lookup, 'exact', pk, pk = pk_field.get_db_prep_lookup('exact', pk,
connection=self.get_queryset().query.connection) connection=self.get_queryset().query.connection)
if isinstance(pk, list): if isinstance(pk, list):
pk = pk[0] pk = pk[0]

View File

@ -46,7 +46,7 @@ class DecimalFieldTests(django.test.TestCase):
def test_get_db_prep_lookup(self): def test_get_db_prep_lookup(self):
from django.db import connection from django.db import connection
f = models.DecimalField(max_digits=5, decimal_places=1) f = models.DecimalField(max_digits=5, decimal_places=1)
self.assertEqual(f.get_db_prep_lookup('exact', None, connection), [None]) self.assertEqual(f.get_db_prep_lookup('exact', None, connection=connection), [None])
def test_filter_with_strings(self): def test_filter_with_strings(self):
""" """
@ -100,13 +100,13 @@ class DateTimeFieldTests(unittest.TestCase):
class BooleanFieldTests(unittest.TestCase): class BooleanFieldTests(unittest.TestCase):
def _test_get_db_prep_lookup(self, f): def _test_get_db_prep_lookup(self, f):
from django.db import connection from django.db import connection
self.assertEqual(f.get_db_prep_lookup('exact', True, connection), [True]) self.assertEqual(f.get_db_prep_lookup('exact', True, connection=connection), [True])
self.assertEqual(f.get_db_prep_lookup('exact', '1', connection), [True]) self.assertEqual(f.get_db_prep_lookup('exact', '1', connection=connection), [True])
self.assertEqual(f.get_db_prep_lookup('exact', 1, connection), [True]) self.assertEqual(f.get_db_prep_lookup('exact', 1, connection=connection), [True])
self.assertEqual(f.get_db_prep_lookup('exact', False, connection), [False]) self.assertEqual(f.get_db_prep_lookup('exact', False, connection=connection), [False])
self.assertEqual(f.get_db_prep_lookup('exact', '0', connection), [False]) self.assertEqual(f.get_db_prep_lookup('exact', '0', connection=connection), [False])
self.assertEqual(f.get_db_prep_lookup('exact', 0, connection), [False]) self.assertEqual(f.get_db_prep_lookup('exact', 0, connection=connection), [False])
self.assertEqual(f.get_db_prep_lookup('exact', None, connection), [None]) self.assertEqual(f.get_db_prep_lookup('exact', None, connection=connection), [None])
def test_booleanfield_get_db_prep_lookup(self): def test_booleanfield_get_db_prep_lookup(self):
self._test_get_db_prep_lookup(models.BooleanField()) self._test_get_db_prep_lookup(models.BooleanField())