mirror of
https://github.com/django/django.git
synced 2025-07-04 17:59:13 +00:00
[soc2010/query-refactor] Introced NativeAutoField, also started with some basic MongoDB tests (really just very basic ORM tests), and introduced various APIs into the mongodb backend that were necessary for running unittests.
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2010/query-refactor@13338 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
defc494810
commit
89fb7aa310
@ -1,8 +1,9 @@
|
|||||||
from pymongo import Connection
|
from pymongo import Connection
|
||||||
|
|
||||||
from django.db.backends import BaseDatabaseWrapper
|
from django.db.backends import BaseDatabaseWrapper, BaseDatabaseValidation
|
||||||
from django.db.backends.signals import connection_created
|
from django.db.backends.signals import connection_created
|
||||||
from django.contrib.mongodb.creation import DatabaseCreation
|
from django.contrib.mongodb.creation import DatabaseCreation
|
||||||
|
from django.contrib.mongodb.introspection import DatabaseIntrospection
|
||||||
from django.utils.importlib import import_module
|
from django.utils.importlib import import_module
|
||||||
|
|
||||||
|
|
||||||
@ -12,9 +13,11 @@ class DatabaseFeatures(object):
|
|||||||
|
|
||||||
class DatabaseOperations(object):
|
class DatabaseOperations(object):
|
||||||
compiler_module = "django.contrib.mongodb.compiler"
|
compiler_module = "django.contrib.mongodb.compiler"
|
||||||
|
sql_ddl = False
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, connection):
|
||||||
self._cache = {}
|
self._cache = {}
|
||||||
|
self.connection = connection
|
||||||
|
|
||||||
def max_name_length(self):
|
def max_name_length(self):
|
||||||
return 254
|
return 254
|
||||||
@ -34,13 +37,23 @@ class DatabaseOperations(object):
|
|||||||
import_module(self.compiler_module), compiler_name
|
import_module(self.compiler_module), compiler_name
|
||||||
)
|
)
|
||||||
return self._cache[compiler_name]
|
return self._cache[compiler_name]
|
||||||
|
|
||||||
|
def flush(self, only_django=False):
|
||||||
|
if only_django:
|
||||||
|
tables = self.connection.introspection.django_table_names(only_existing=True)
|
||||||
|
else:
|
||||||
|
tables = self.connection.introspection.table_names()
|
||||||
|
for table in tables:
|
||||||
|
self.connection.db.drop_collection(table)
|
||||||
|
|
||||||
class DatabaseWrapper(BaseDatabaseWrapper):
|
class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(DatabaseWrapper, self).__init__(*args, **kwargs)
|
super(DatabaseWrapper, self).__init__(*args, **kwargs)
|
||||||
self.features = DatabaseFeatures()
|
self.features = DatabaseFeatures()
|
||||||
self.ops = DatabaseOperations()
|
self.ops = DatabaseOperations(self)
|
||||||
self.creation = DatabaseCreation(self)
|
self.creation = DatabaseCreation(self)
|
||||||
|
self.validation = BaseDatabaseValidation(self)
|
||||||
|
self.introspection = DatabaseIntrospection(self)
|
||||||
self._connection = None
|
self._connection = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -11,6 +11,7 @@ class DatabaseCreation(object):
|
|||||||
else:
|
else:
|
||||||
test_database_name = TEST_DATABASE_PREFIX + self.connection.settings_dict['NAME']
|
test_database_name = TEST_DATABASE_PREFIX + self.connection.settings_dict['NAME']
|
||||||
self.connection.settings_dict["NAME"] = test_database_name
|
self.connection.settings_dict["NAME"] = test_database_name
|
||||||
|
self.connection.settings_dict["SUPPORTS_TRANSACTIONS"] = False
|
||||||
return test_database_name
|
return test_database_name
|
||||||
|
|
||||||
def destroy_test_db(self, old_database_name, verbosity=1):
|
def destroy_test_db(self, old_database_name, verbosity=1):
|
||||||
|
6
django/contrib/mongodb/introspection.py
Normal file
6
django/contrib/mongodb/introspection.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
from django.db.backends import BaseDatabaseIntrospection
|
||||||
|
|
||||||
|
|
||||||
|
class DatabaseIntrospection(BaseDatabaseIntrospection):
|
||||||
|
def table_names(self):
|
||||||
|
return self.connection.db.collection_names()
|
@ -35,9 +35,7 @@ class Command(NoArgsCommand):
|
|||||||
import_module('.management', app_name)
|
import_module('.management', app_name)
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
sql_list = sql_flush(self.style, connection, only_django=True)
|
|
||||||
|
|
||||||
if interactive:
|
if interactive:
|
||||||
confirm = raw_input("""You have requested a flush of the database.
|
confirm = raw_input("""You have requested a flush of the database.
|
||||||
This will IRREVERSIBLY DESTROY all data currently in the %r database,
|
This will IRREVERSIBLY DESTROY all data currently in the %r database,
|
||||||
@ -49,6 +47,11 @@ Are you sure you want to do this?
|
|||||||
confirm = 'yes'
|
confirm = 'yes'
|
||||||
|
|
||||||
if confirm == 'yes':
|
if confirm == 'yes':
|
||||||
|
# TODO: HACK, make this more OO.
|
||||||
|
if not getattr(connection.ops, "sql_ddl", True):
|
||||||
|
connection.ops.flush(only_django=True)
|
||||||
|
return
|
||||||
|
sql_list = sql_flush(self.style, connection, only_django=True)
|
||||||
try:
|
try:
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
for sql in sql_list:
|
for sql in sql_list:
|
||||||
|
@ -447,17 +447,32 @@ class Field(object):
|
|||||||
"Returns the value of this field in the given model instance."
|
"Returns the value of this field in the given model instance."
|
||||||
return getattr(obj, self.attname)
|
return getattr(obj, self.attname)
|
||||||
|
|
||||||
class AutoField(Field):
|
class BaseAutoField(Field):
|
||||||
|
empty_strings_allowed = False
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
assert kwargs.get('primary_key'), "%ss must have primary_key=True." % self.__class__.__name__
|
||||||
|
kwargs['blank'] = True
|
||||||
|
super(BaseAutoField, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def contribute_to_class(self, cls, name):
|
||||||
|
assert not cls._meta.has_auto_field, "A model can't have more than one AutoField."
|
||||||
|
super(BaseAutoField, self).contribute_to_class(cls, name)
|
||||||
|
cls._meta.has_auto_field = True
|
||||||
|
cls._meta.auto_field = self
|
||||||
|
|
||||||
|
def get_internal_type(self):
|
||||||
|
return "AutoField"
|
||||||
|
|
||||||
|
def formfield(self, **kwargs):
|
||||||
|
return None
|
||||||
|
|
||||||
|
class AutoField(BaseAutoField):
|
||||||
description = _("Integer")
|
description = _("Integer")
|
||||||
|
|
||||||
empty_strings_allowed = False
|
|
||||||
default_error_messages = {
|
default_error_messages = {
|
||||||
'invalid': _(u'This value must be an integer.'),
|
'invalid': _(u'This value must be an integer.'),
|
||||||
}
|
}
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
assert kwargs.get('primary_key', False) is True, "%ss must have primary_key=True." % self.__class__.__name__
|
|
||||||
kwargs['blank'] = True
|
|
||||||
Field.__init__(self, *args, **kwargs)
|
|
||||||
|
|
||||||
def to_python(self, value):
|
def to_python(self, value):
|
||||||
if value is None:
|
if value is None:
|
||||||
@ -475,14 +490,10 @@ class AutoField(Field):
|
|||||||
return None
|
return None
|
||||||
return int(value)
|
return int(value)
|
||||||
|
|
||||||
def contribute_to_class(self, cls, name):
|
class NativeAutoField(BaseAutoField):
|
||||||
assert not cls._meta.has_auto_field, "A model can't have more than one AutoField."
|
# TODO: eventually delegate validation and other such things to the
|
||||||
super(AutoField, self).contribute_to_class(cls, name)
|
# backends. For now it's enough that this class exists.
|
||||||
cls._meta.has_auto_field = True
|
pass
|
||||||
cls._meta.auto_field = self
|
|
||||||
|
|
||||||
def formfield(self, **kwargs):
|
|
||||||
return None
|
|
||||||
|
|
||||||
class BooleanField(Field):
|
class BooleanField(Field):
|
||||||
empty_strings_allowed = False
|
empty_strings_allowed = False
|
||||||
|
0
tests/regressiontests/mongodb/__init__.py
Normal file
0
tests/regressiontests/mongodb/__init__.py
Normal file
10
tests/regressiontests/mongodb/models.py
Normal file
10
tests/regressiontests/mongodb/models.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class Artist(models.Model):
|
||||||
|
id = models.NativeAutoField(primary_key=True)
|
||||||
|
name = models.CharField(max_length=255)
|
||||||
|
good = models.BooleanField()
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return self.name
|
11
tests/regressiontests/mongodb/tests.py
Normal file
11
tests/regressiontests/mongodb/tests.py
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from models import Artist
|
||||||
|
|
||||||
|
|
||||||
|
class MongoTestCase(TestCase):
|
||||||
|
def test_create(self):
|
||||||
|
b = Artist.objects.create(name="Bruce Springsteen", good=True)
|
||||||
|
self.assertTrue(b.pk is not None)
|
||||||
|
self.assertEqual(b.name, "Bruce Springsteen")
|
||||||
|
self.assertTrue(b.good)
|
Loading…
x
Reference in New Issue
Block a user