Merge remote-tracking branch 'upstream/master' into pr-document-modify

This commit is contained in:
Dmitry Konishchev 2014-11-02 17:24:51 +03:00
commit bc9aff8c60
11 changed files with 44 additions and 7 deletions

View File

@ -210,3 +210,4 @@ that much better:
* Jay Shirley (https://github.com/jshirley) * Jay Shirley (https://github.com/jshirley)
* DavidBord (https://github.com/DavidBord) * DavidBord (https://github.com/DavidBord)
* Axel Haustant (https://github.com/noirbizarre) * Axel Haustant (https://github.com/noirbizarre)
* David Czarnecki (https://github.com/czarneckid)

View File

@ -5,6 +5,8 @@ Changelog
Changes in 0.9.X - DEV Changes in 0.9.X - DEV
====================== ======================
- Add Support For MongoDB 2.6.X's maxTimeMS #778
- abstract shouldn't be inherited in EmbeddedDocument # 789
- Allow specifying the '_cls' as a field for indexes #397 - Allow specifying the '_cls' as a field for indexes #397
- Stop ensure_indexes running on a secondaries unless connection is through mongos #746 - Stop ensure_indexes running on a secondaries unless connection is through mongos #746
- Not overriding default values when loading a subset of fields #399 - Not overriding default values when loading a subset of fields #399
@ -54,6 +56,8 @@ Changes in 0.9.X - DEV
- Allow atomic update for the entire `DictField` #742 - Allow atomic update for the entire `DictField` #742
- Added MultiPointField, MultiLineField, MultiPolygonField - Added MultiPointField, MultiLineField, MultiPolygonField
- Fix multiple connections aliases being rewritten #748 - Fix multiple connections aliases being rewritten #748
- Fixed a few instances where reverse_delete_rule was written as reverse_delete_rules. #791
Changes in 0.8.7 Changes in 0.8.7
================ ================

View File

@ -145,7 +145,7 @@ cleaner looking while still allowing manual execution of the callback::
ReferenceFields and Signals ReferenceFields and Signals
--------------------------- ---------------------------
Currently `reverse_delete_rules` do not trigger signals on the other part of Currently `reverse_delete_rule` does not trigger signals on the other part of
the relationship. If this is required you must manually handle the the relationship. If this is required you must manually handle the
reverse deletion. reverse deletion.

View File

@ -46,4 +46,6 @@ Next, start a text search using :attr:`QuerySet.search_text` method::
Ordering by text score Ordering by text score
====================== ======================
::
objects = News.objects.search('mongo').order_by('$text_score') objects = News.objects.search('mongo').order_by('$text_score')

View File

@ -15,7 +15,7 @@ import django
__all__ = (list(document.__all__) + fields.__all__ + connection.__all__ + __all__ = (list(document.__all__) + fields.__all__ + connection.__all__ +
list(queryset.__all__) + signals.__all__ + list(errors.__all__)) list(queryset.__all__) + signals.__all__ + list(errors.__all__))
VERSION = (0, 8, 7) VERSION = (0, 9, 0)
def get_version(): def get_version():

View File

@ -46,8 +46,9 @@ class DocumentMetaclass(type):
elif hasattr(base, '_meta'): elif hasattr(base, '_meta'):
meta.merge(base._meta) meta.merge(base._meta)
attrs['_meta'] = meta attrs['_meta'] = meta
attrs['_meta']['abstract'] = False # 789: EmbeddedDocument shouldn't inherit abstract
if '_meta' in attrs and attrs['_meta'].get('allow_inheritance', ALLOW_INHERITANCE): if attrs['_meta'].get('allow_inheritance', ALLOW_INHERITANCE):
StringField = _import_class('StringField') StringField = _import_class('StringField')
attrs['_cls'] = StringField() attrs['_cls'] = StringField()

View File

@ -859,7 +859,7 @@ class ReferenceField(BaseField):
Use the `reverse_delete_rule` to handle what should happen if the document Use the `reverse_delete_rule` to handle what should happen if the document
the field is referencing is deleted. EmbeddedDocuments, DictFields and the field is referencing is deleted. EmbeddedDocuments, DictFields and
MapFields do not support reverse_delete_rules and an `InvalidDocumentError` MapFields does not support reverse_delete_rule and an `InvalidDocumentError`
will be raised if trying to set on one of these Document / Field types. will be raised if trying to set on one of these Document / Field types.
The options are: The options are:
@ -883,7 +883,7 @@ class ReferenceField(BaseField):
Bar.register_delete_rule(Foo, 'bar', NULLIFY) Bar.register_delete_rule(Foo, 'bar', NULLIFY)
.. note :: .. note ::
`reverse_delete_rules` do not trigger pre / post delete signals to be `reverse_delete_rule` does not trigger pre / post delete signals to be
triggered. triggered.
.. versionchanged:: 0.5 added `reverse_delete_rule` .. versionchanged:: 0.5 added `reverse_delete_rule`

View File

@ -82,6 +82,7 @@ class BaseQuerySet(object):
self._skip = None self._skip = None
self._hint = -1 # Using -1 as None is a valid value for hint self._hint = -1 # Using -1 as None is a valid value for hint
self.only_fields = [] self.only_fields = []
self._max_time_ms = None
def __call__(self, q_obj=None, class_check=True, slave_okay=False, def __call__(self, q_obj=None, class_check=True, slave_okay=False,
read_preference=None, **query): read_preference=None, **query):
@ -672,7 +673,7 @@ class BaseQuerySet(object):
'_timeout', '_class_check', '_slave_okay', '_read_preference', '_timeout', '_class_check', '_slave_okay', '_read_preference',
'_iter', '_scalar', '_as_pymongo', '_as_pymongo_coerce', '_iter', '_scalar', '_as_pymongo', '_as_pymongo_coerce',
'_limit', '_skip', '_hint', '_auto_dereference', '_limit', '_skip', '_hint', '_auto_dereference',
'_search_text', '_include_text_scores', 'only_fields') '_search_text', '_include_text_scores', 'only_fields', '_max_time_ms')
for prop in copy_props: for prop in copy_props:
val = getattr(self, prop) val = getattr(self, prop)
@ -969,6 +970,13 @@ class BaseQuerySet(object):
queryset._as_pymongo_coerce = coerce_types queryset._as_pymongo_coerce = coerce_types
return queryset return queryset
def max_time_ms(self, ms):
"""Wait `ms` milliseconds before killing the query on the server
:param ms: the number of milliseconds before killing the query on the server
"""
return self._chainable_method("max_time_ms", ms)
# JSON Helpers # JSON Helpers
def to_json(self, *args, **kwargs): def to_json(self, *args, **kwargs):
@ -1700,6 +1708,13 @@ class BaseQuerySet(object):
code) code)
return code return code
def _chainable_method(self, method_name, val):
queryset = self.clone()
method = getattr(queryset._cursor, method_name)
method(val)
setattr(queryset, "_" + method_name, val)
return queryset
# Deprecated # Deprecated
def ensure_index(self, **kwargs): def ensure_index(self, **kwargs):
"""Deprecated use :func:`Document.ensure_index`""" """Deprecated use :func:`Document.ensure_index`"""

View File

@ -397,6 +397,16 @@ class InheritanceTest(unittest.TestCase):
meta = {'abstract': True} meta = {'abstract': True}
self.assertRaises(ValueError, create_bad_abstract) self.assertRaises(ValueError, create_bad_abstract)
def test_abstract_embedded_documents(self):
# 789: EmbeddedDocument shouldn't inherit abstract
class A(EmbeddedDocument):
meta = {"abstract": True}
class B(A):
pass
self.assertFalse(B._meta["abstract"])
def test_inherited_collections(self): def test_inherited_collections(self):
"""Ensure that subclassed documents don't override parents' """Ensure that subclassed documents don't override parents'
collections collections

View File

@ -1858,7 +1858,7 @@ class InstanceTest(unittest.TestCase):
self.assertEqual(Bar.objects.count(), 1) # No effect on the BlogPost self.assertEqual(Bar.objects.count(), 1) # No effect on the BlogPost
self.assertEqual(Bar.objects.get().foo, None) self.assertEqual(Bar.objects.get().foo, None)
def test_invalid_reverse_delete_rules_raise_errors(self): def test_invalid_reverse_delete_rule_raise_errors(self):
def throw_invalid_document_error(): def throw_invalid_document_error():
class Blog(Document): class Blog(Document):

View File

@ -4401,6 +4401,10 @@ class QuerySetTest(unittest.TestCase):
self.Person.objects().delete() self.Person.objects().delete()
self.assertEqual(self.Person.objects().skip(1).delete(), 0) # test Document delete without existing documents self.assertEqual(self.Person.objects().skip(1).delete(), 0) # test Document delete without existing documents
def test_max_time_ms(self):
# 778: max_time_ms can get only int or None as input
self.assertRaises(TypeError, self.Person.objects(name="name").max_time_ms, "not a number")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()