Skip to content

Commit fe2bd63

Browse files
committed
[soc2010/query-refactor] MongoDB backend can now update saved objects.
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2010/query-refactor@13340 bcc190cf-cafb-0310-a4f2-bffc1f526a37
1 parent 9142ba5 commit fe2bd63

File tree

4 files changed

+60
-0
lines changed

4 files changed

+60
-0
lines changed

django/contrib/mongodb/base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
class DatabaseFeatures(object):
1111
interprets_empty_strings_as_nulls = False
12+
typed_columns = False
1213

1314

1415
class DatabaseOperations(object):

django/contrib/mongodb/compiler.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,54 @@ def __init__(self, query, connection, using):
44
self.query = query
55
self.connection = connection
66
self.using = using
7+
8+
def get_filters(self, where):
9+
assert where.connector == "AND"
10+
assert not where.negated
11+
filters = {}
12+
for child in where.children:
13+
if isinstance(child, self.query.where_class):
14+
# TODO: probably needs to check for dupe keys
15+
filters.update(self.get_filters(child))
16+
else:
17+
field, val = self.make_atom(*child)
18+
filters[field] = val
19+
return filters
20+
21+
def make_atom(self, lhs, lookup_type, value_annotation, params_or_value):
22+
assert lookup_type == "exact"
23+
if hasattr(lhs, "process"):
24+
lhs, params = lhs.process(lookup_type, params_or_value, self.connection)
25+
else:
26+
params = Field().get_db_prep_lookup(lookup_type, params_or_value,
27+
connection=self.connection, prepared=True)
28+
assert isinstance(lhs, (list, tuple))
29+
table, column, _ = lhs
30+
assert table == self.query.model._meta.db_table
31+
if column == self.query.model._meta.pk.column:
32+
column = "_id"
33+
return column, params[0]
34+
35+
def build_query(self):
36+
assert not self.query.aggregates
37+
assert len(self.query.alias_map) == 1
38+
assert self.query.default_cols
39+
assert not self.query.distinct
40+
assert not self.query.extra
41+
assert not self.query.having
42+
assert self.query.high_mark is None
43+
assert not self.query.order_by
44+
45+
filters = self.get_filters(self.query.where)
46+
return self.connection.db[self.query.model._meta.db_table].find(filters)
47+
48+
def has_results(self):
49+
try:
50+
self.build_query()[0]
51+
except IndexError:
52+
return False
53+
else:
54+
return True
755

856

957
class SQLInsertCompiler(SQLCompiler):

django/db/models/fields/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,8 @@ def db_type(self, connection):
215215
# mapped to one of the built-in Django field types. In this case, you
216216
# can implement db_type() instead of get_internal_type() to specify
217217
# exactly which wacky database column type you want to use.
218+
if not getattr(connection.features, "typed_columns", True):
219+
return None
218220
data = DictWrapper(self.__dict__, connection.ops.quote_name, "qn_")
219221
try:
220222
return connection.creation.data_types[self.get_internal_type()] % data

tests/regressiontests/mongodb/tests.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,12 @@ def test_create(self):
99
self.assertTrue(b.pk is not None)
1010
self.assertEqual(b.name, "Bruce Springsteen")
1111
self.assertTrue(b.good)
12+
13+
def test_update(self):
14+
l = Artist.objects.create(name="Lady Gaga", good=True)
15+
self.assertTrue(l.pk is not None)
16+
pk = l.pk
17+
# Whoops, we screwed up.
18+
l.good = False
19+
l.save()
20+
self.assertEqual(l.pk, pk)

0 commit comments

Comments
 (0)