Kirill Mavreshko avatar 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

django_mongodb/base.py

     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
     

django_mongodb/query.py

 
 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 = self.model._meta.pk
         if isinstance(node, tuple):
             lvalue, lookup_type, value_annot, params = node
                 res = {field_name: {parent_negated and "$nin" or "$in": params}}
             else:
                 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)
+                
         else:
             # 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
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.