Kirill Mavreshko committed ea9d491

Automatic conversion unknown types in queries (for old apps)

Comments (0)

Files changed (3)

+- fixtures for Django tests
 - storing files in MongoDB using GridFS
 - special version of ForeignKey for embedding objects
 - automated ensure_index() before query and order


     def connection(self):
         if self._connection is None:
             from pymongo.connection import Connection
-            self._connection = Connection(self.settings_dict['DATABASE_HOST'], int(self.settings_dict['DATABASE_PORT']))
+            DEFAULT_DATABASE_HOST = 'localhost'
+            DEFAULT_DATABASE_PORT = '27017'
+            self._connection = Connection(
+                self.settings_dict['DATABASE_HOST'] or DEFAULT_DATABASE_HOST,
+                int(self.settings_dict['DATABASE_PORT'] or DEFAULT_DATABASE_PORT))
         return self._connection


 import re, sys
 from copy import deepcopy
+import datetime
 from pymongo.objectid import ObjectId
 from pymongo import ASCENDING, DESCENDING
+from pymongo.binary import Binary
+from pymongo.code import Code
+from pymongo.dbref import DBRef
+from pymongo.bson import _RE_TYPE
 from django.db import DatabaseError
 from django.db.models.sql.query import BaseQuery
 from django.db.models.sql.where import AND, OR
 from django.utils.datastructures import SortedDict
+_VALID_MONGO_FIELD_TYPES = (int, long, float, basestring, dict, tuple, list, _RE_TYPE, datetime.datetime, ObjectId, Binary, Code)
 class MongoDbQuery(BaseQuery):
     Alternative of django.db.models.query.sql.BaseQuery for MongoDB
         to query dict for MongoDB "find" collection method.
         from django.db import models
+        from pymongo.bson import _element_to_bson, _RE_TYPE
+        from pymongo.errors import InvalidDocument
         pk_field =
         if isinstance(node, tuple):
             lvalue, lookup_type, value_annot, params = node
                 res = {field_name: {parent_negated and "$nin" or "$in": params}}
                 raise DatabaseError("Unsupported lookup type: %r" % lookup_type)
+            fval = res[field_name]
+            if fval is not None and not isinstance(fval, _VALID_MONGO_FIELD_TYPES):
+                try:
+                    _element_to_bson(field_name, fval, False)
+                except InvalidDocument:
+                    try:
+                        res[field_name] = int(fval)
+                    except ValueError:
+                        try:
+                            res[field_name] = str(fval)
+                        except:
+                            raise "Unsupported value type %r for document field %r" % (
+                                type(fval), field_name)
             # Trying eliminate OR and NOT.
             # TODO: Need better condition validator
         result = collection.find(query, **limit_params)
         if sort_opts:
             result = result.sort(sort_opts)
         nothing = False
         while not nothing:
             i = 0