diff --git a/django/contrib/mongodb/base.py b/django/contrib/mongodb/base.py index e92c6db25f..1fc8a26770 100644 --- a/django/contrib/mongodb/base.py +++ b/django/contrib/mongodb/base.py @@ -9,6 +9,7 @@ from django.utils.importlib import import_module class DatabaseFeatures(object): interprets_empty_strings_as_nulls = False + typed_columns = False class DatabaseOperations(object): diff --git a/django/contrib/mongodb/compiler.py b/django/contrib/mongodb/compiler.py index d936af8f26..0d7f1f517c 100644 --- a/django/contrib/mongodb/compiler.py +++ b/django/contrib/mongodb/compiler.py @@ -4,6 +4,54 @@ class SQLCompiler(object): self.query = query self.connection = connection self.using = using + + def get_filters(self, where): + assert where.connector == "AND" + assert not where.negated + filters = {} + for child in where.children: + if isinstance(child, self.query.where_class): + # TODO: probably needs to check for dupe keys + filters.update(self.get_filters(child)) + else: + field, val = self.make_atom(*child) + filters[field] = val + return filters + + def make_atom(self, lhs, lookup_type, value_annotation, params_or_value): + assert lookup_type == "exact" + if hasattr(lhs, "process"): + lhs, params = lhs.process(lookup_type, params_or_value, self.connection) + else: + params = Field().get_db_prep_lookup(lookup_type, params_or_value, + connection=self.connection, prepared=True) + assert isinstance(lhs, (list, tuple)) + table, column, _ = lhs + assert table == self.query.model._meta.db_table + if column == self.query.model._meta.pk.column: + column = "_id" + return column, params[0] + + def build_query(self): + assert not self.query.aggregates + assert len(self.query.alias_map) == 1 + assert self.query.default_cols + assert not self.query.distinct + assert not self.query.extra + assert not self.query.having + assert self.query.high_mark is None + assert not self.query.order_by + + filters = self.get_filters(self.query.where) + return self.connection.db[self.query.model._meta.db_table].find(filters) + + def has_results(self): + try: + self.build_query()[0] + except IndexError: + return False + else: + return True class SQLInsertCompiler(SQLCompiler): diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 0c9b603609..d6da57b467 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -215,6 +215,8 @@ class Field(object): # mapped to one of the built-in Django field types. In this case, you # can implement db_type() instead of get_internal_type() to specify # exactly which wacky database column type you want to use. + if not getattr(connection.features, "typed_columns", True): + return None data = DictWrapper(self.__dict__, connection.ops.quote_name, "qn_") try: return connection.creation.data_types[self.get_internal_type()] % data diff --git a/tests/regressiontests/mongodb/tests.py b/tests/regressiontests/mongodb/tests.py index cbf0dcbcd8..75a2dbf08b 100644 --- a/tests/regressiontests/mongodb/tests.py +++ b/tests/regressiontests/mongodb/tests.py @@ -9,3 +9,12 @@ class MongoTestCase(TestCase): self.assertTrue(b.pk is not None) self.assertEqual(b.name, "Bruce Springsteen") self.assertTrue(b.good) + + def test_update(self): + l = Artist.objects.create(name="Lady Gaga", good=True) + self.assertTrue(l.pk is not None) + pk = l.pk + # Whoops, we screwed up. + l.good = False + l.save() + self.assertEqual(l.pk, pk)