Merge branch 'master' of https://github.com/MongoEngine/mongoengine
This commit is contained in:
commit
85e271098f
@ -9,6 +9,9 @@ MongoEngine
|
|||||||
.. image:: https://secure.travis-ci.org/MongoEngine/mongoengine.png?branch=master
|
.. image:: https://secure.travis-ci.org/MongoEngine/mongoengine.png?branch=master
|
||||||
:target: http://travis-ci.org/MongoEngine/mongoengine
|
:target: http://travis-ci.org/MongoEngine/mongoengine
|
||||||
|
|
||||||
|
.. image:: https://coveralls.io/repos/MongoEngine/mongoengine/badge.png?branch=master
|
||||||
|
:target: https://coveralls.io/r/MongoEngine/mongoengine?branch=master
|
||||||
|
|
||||||
About
|
About
|
||||||
=====
|
=====
|
||||||
MongoEngine is a Python Object-Document Mapper for working with MongoDB.
|
MongoEngine is a Python Object-Document Mapper for working with MongoDB.
|
||||||
@ -92,4 +95,4 @@ Community
|
|||||||
|
|
||||||
Contributing
|
Contributing
|
||||||
============
|
============
|
||||||
We welcome contributions! see the`Contribution guidelines <https://github.com/MongoEngine/mongoengine/blob/master/CONTRIBUTING.rst>`_
|
We welcome contributions! see the `Contribution guidelines <https://github.com/MongoEngine/mongoengine/blob/master/CONTRIBUTING.rst>`_
|
||||||
|
@ -38,6 +38,7 @@ Context Managers
|
|||||||
================
|
================
|
||||||
|
|
||||||
.. autoclass:: mongoengine.context_managers.switch_db
|
.. autoclass:: mongoengine.context_managers.switch_db
|
||||||
|
.. autoclass:: mongoengine.context_managers.switch_collection
|
||||||
.. autoclass:: mongoengine.context_managers.no_dereference
|
.. autoclass:: mongoengine.context_managers.no_dereference
|
||||||
.. autoclass:: mongoengine.context_managers.query_counter
|
.. autoclass:: mongoengine.context_managers.query_counter
|
||||||
|
|
||||||
|
@ -2,6 +2,12 @@
|
|||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
Changes in 0.8.7
|
||||||
|
================
|
||||||
|
- Calling reload on deleted / nonexistant documents raises DoesNotExist (#538)
|
||||||
|
- Stop ensure_indexes running on a secondaries (#555)
|
||||||
|
- Fix circular import issue with django auth (#531) (#545)
|
||||||
|
|
||||||
Changes in 0.8.6
|
Changes in 0.8.6
|
||||||
================
|
================
|
||||||
- Fix django auth import (#531)
|
- Fix django auth import (#531)
|
||||||
|
@ -100,3 +100,18 @@ access to the same User document across databases::
|
|||||||
|
|
||||||
.. note:: Make sure any aliases have been registered with
|
.. note:: Make sure any aliases have been registered with
|
||||||
:func:`~mongoengine.register_connection` before using the context manager.
|
:func:`~mongoengine.register_connection` before using the context manager.
|
||||||
|
|
||||||
|
There is also a switch collection context manager as well. The
|
||||||
|
:class:`~mongoengine.context_managers.switch_collection` context manager allows
|
||||||
|
you to change the collection for a given class allowing quick and easy
|
||||||
|
access to the same Group document across collection::
|
||||||
|
|
||||||
|
from mongoengine.context_managers import switch_db
|
||||||
|
|
||||||
|
class Group(Document):
|
||||||
|
name = StringField()
|
||||||
|
|
||||||
|
Group(name="test").save() # Saves in the default db
|
||||||
|
|
||||||
|
with switch_collection(Group, 'group2000') as Group:
|
||||||
|
Group(name="hello Group 2000 collection!").save() # Saves in group2000 collection
|
||||||
|
@ -92,8 +92,8 @@ were added in 0.8 for: :class:`~mongoengine.fields.PointField`,
|
|||||||
* ``geo_within`` -- Check if a geometry is within a polygon. For ease of use
|
* ``geo_within`` -- Check if a geometry is within a polygon. For ease of use
|
||||||
it accepts either a geojson geometry or just the polygon coordinates eg::
|
it accepts either a geojson geometry or just the polygon coordinates eg::
|
||||||
|
|
||||||
loc.objects(point__geo_with=[[[40, 5], [40, 6], [41, 6], [40, 5]]])
|
loc.objects(point__geo_within=[[[40, 5], [40, 6], [41, 6], [40, 5]]])
|
||||||
loc.objects(point__geo_with={"type": "Polygon",
|
loc.objects(point__geo_within={"type": "Polygon",
|
||||||
"coordinates": [[[40, 5], [40, 6], [41, 6], [40, 5]]]})
|
"coordinates": [[[40, 5], [40, 6], [41, 6], [40, 5]]]})
|
||||||
|
|
||||||
* ``geo_within_box`` - simplified geo_within searching with a box eg::
|
* ``geo_within_box`` - simplified geo_within searching with a box eg::
|
||||||
|
@ -2,6 +2,12 @@
|
|||||||
Upgrading
|
Upgrading
|
||||||
#########
|
#########
|
||||||
|
|
||||||
|
0.8.7
|
||||||
|
*****
|
||||||
|
|
||||||
|
Calling reload on deleted / nonexistant documents now raises a DoesNotExist
|
||||||
|
exception.
|
||||||
|
|
||||||
|
|
||||||
0.8.2 to 0.8.3
|
0.8.2 to 0.8.3
|
||||||
**************
|
**************
|
||||||
@ -270,7 +276,7 @@ queryset you should upgrade to use count::
|
|||||||
len(Animal.objects(type="mammal"))
|
len(Animal.objects(type="mammal"))
|
||||||
|
|
||||||
# New code
|
# New code
|
||||||
Animal.objects(type="mammal").count())
|
Animal.objects(type="mammal").count()
|
||||||
|
|
||||||
|
|
||||||
.only() now inline with .exclude()
|
.only() now inline with .exclude()
|
||||||
|
@ -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, 6)
|
VERSION = (0, 8, 7)
|
||||||
|
|
||||||
|
|
||||||
def get_version():
|
def get_version():
|
||||||
|
@ -9,7 +9,6 @@ from django.contrib.auth.models import AnonymousUser
|
|||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from .utils import datetime_now
|
from .utils import datetime_now
|
||||||
from .mongo_auth.models import get_user_document
|
|
||||||
|
|
||||||
REDIRECT_FIELD_NAME = 'next'
|
REDIRECT_FIELD_NAME = 'next'
|
||||||
|
|
||||||
@ -382,9 +381,10 @@ class MongoEngineBackend(object):
|
|||||||
supports_object_permissions = False
|
supports_object_permissions = False
|
||||||
supports_anonymous_user = False
|
supports_anonymous_user = False
|
||||||
supports_inactive_user = False
|
supports_inactive_user = False
|
||||||
|
_user_doc = False
|
||||||
|
|
||||||
def authenticate(self, username=None, password=None):
|
def authenticate(self, username=None, password=None):
|
||||||
user = get_user_document().objects(username=username).first()
|
user = self.user_document.objects(username=username).first()
|
||||||
if user:
|
if user:
|
||||||
if password and user.check_password(password):
|
if password and user.check_password(password):
|
||||||
backend = auth.get_backends()[0]
|
backend = auth.get_backends()[0]
|
||||||
@ -393,8 +393,14 @@ class MongoEngineBackend(object):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def get_user(self, user_id):
|
def get_user(self, user_id):
|
||||||
return get_user_document().objects.with_id(user_id)
|
return self.user_document.objects.with_id(user_id)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def user_document(self):
|
||||||
|
if self._user_doc is False:
|
||||||
|
from .mongo_auth.models import get_user_document
|
||||||
|
self._user_doc = get_user_document()
|
||||||
|
return self._user_doc
|
||||||
|
|
||||||
def get_user(userid):
|
def get_user(userid):
|
||||||
"""Returns a User object from an id (User.id). Django's equivalent takes
|
"""Returns a User object from an id (User.id). Django's equivalent takes
|
||||||
|
@ -12,6 +12,7 @@ from mongoengine.common import _import_class
|
|||||||
from mongoengine.base import (DocumentMetaclass, TopLevelDocumentMetaclass,
|
from mongoengine.base import (DocumentMetaclass, TopLevelDocumentMetaclass,
|
||||||
BaseDocument, BaseDict, BaseList,
|
BaseDocument, BaseDict, BaseList,
|
||||||
ALLOW_INHERITANCE, get_document)
|
ALLOW_INHERITANCE, get_document)
|
||||||
|
from mongoengine.errors import ValidationError
|
||||||
from mongoengine.queryset import OperationError, NotUniqueError, QuerySet
|
from mongoengine.queryset import OperationError, NotUniqueError, QuerySet
|
||||||
from mongoengine.connection import get_db, DEFAULT_CONNECTION_NAME
|
from mongoengine.connection import get_db, DEFAULT_CONNECTION_NAME
|
||||||
from mongoengine.context_managers import switch_db, switch_collection
|
from mongoengine.context_managers import switch_db, switch_collection
|
||||||
@ -280,7 +281,9 @@ class Document(BaseDocument):
|
|||||||
kwargs.update(cascade_kwargs)
|
kwargs.update(cascade_kwargs)
|
||||||
kwargs['_refs'] = _refs
|
kwargs['_refs'] = _refs
|
||||||
self.cascade_save(**kwargs)
|
self.cascade_save(**kwargs)
|
||||||
|
except pymongo.errors.DuplicateKeyError, err:
|
||||||
|
message = u'Tried to save duplicate unique keys (%s)'
|
||||||
|
raise NotUniqueError(message % unicode(err))
|
||||||
except pymongo.errors.OperationFailure, err:
|
except pymongo.errors.OperationFailure, err:
|
||||||
message = 'Could not save document (%s)'
|
message = 'Could not save document (%s)'
|
||||||
if re.match('^E1100[01] duplicate key', unicode(err)):
|
if re.match('^E1100[01] duplicate key', unicode(err)):
|
||||||
@ -450,14 +453,16 @@ class Document(BaseDocument):
|
|||||||
.. versionadded:: 0.1.2
|
.. versionadded:: 0.1.2
|
||||||
.. versionchanged:: 0.6 Now chainable
|
.. versionchanged:: 0.6 Now chainable
|
||||||
"""
|
"""
|
||||||
|
if not self.pk:
|
||||||
|
raise self.DoesNotExist("Document does not exist")
|
||||||
obj = self._qs.read_preference(ReadPreference.PRIMARY).filter(
|
obj = self._qs.read_preference(ReadPreference.PRIMARY).filter(
|
||||||
**self._object_key).limit(1).select_related(max_depth=max_depth)
|
**self._object_key).limit(1).select_related(max_depth=max_depth)
|
||||||
|
|
||||||
|
|
||||||
if obj:
|
if obj:
|
||||||
obj = obj[0]
|
obj = obj[0]
|
||||||
else:
|
else:
|
||||||
msg = "Reloaded document has been deleted"
|
raise self.DoesNotExist("Document does not exist")
|
||||||
raise OperationError(msg)
|
|
||||||
for field in self._fields_ordered:
|
for field in self._fields_ordered:
|
||||||
setattr(self, field, self._reload(field, obj[field]))
|
setattr(self, field, self._reload(field, obj[field]))
|
||||||
self._changed_fields = obj._changed_fields
|
self._changed_fields = obj._changed_fields
|
||||||
@ -547,6 +552,8 @@ class Document(BaseDocument):
|
|||||||
index_cls = cls._meta.get('index_cls', True)
|
index_cls = cls._meta.get('index_cls', True)
|
||||||
|
|
||||||
collection = cls._get_collection()
|
collection = cls._get_collection()
|
||||||
|
if collection.read_preference > 1:
|
||||||
|
return
|
||||||
|
|
||||||
# determine if an index which we are creating includes
|
# determine if an index which we are creating includes
|
||||||
# _cls as its first field; if so, we can avoid creating
|
# _cls as its first field; if so, we can avoid creating
|
||||||
|
@ -302,8 +302,11 @@ class BaseQuerySet(object):
|
|||||||
signals.pre_bulk_insert.send(self._document, documents=docs)
|
signals.pre_bulk_insert.send(self._document, documents=docs)
|
||||||
try:
|
try:
|
||||||
ids = self._collection.insert(raw, **write_concern)
|
ids = self._collection.insert(raw, **write_concern)
|
||||||
|
except pymongo.errors.DuplicateKeyError, err:
|
||||||
|
message = 'Could not save document (%s)';
|
||||||
|
raise NotUniqueError(message % unicode(err))
|
||||||
except pymongo.errors.OperationFailure, err:
|
except pymongo.errors.OperationFailure, err:
|
||||||
message = 'Could not save document (%s)'
|
message = 'Could not save document (%s)';
|
||||||
if re.match('^E1100[01] duplicate key', unicode(err)):
|
if re.match('^E1100[01] duplicate key', unicode(err)):
|
||||||
# E11000 - duplicate key error index
|
# E11000 - duplicate key error index
|
||||||
# E11001 - duplicate key on update
|
# E11001 - duplicate key on update
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
%define srcname mongoengine
|
%define srcname mongoengine
|
||||||
|
|
||||||
Name: python-%{srcname}
|
Name: python-%{srcname}
|
||||||
Version: 0.8.6
|
Version: 0.8.7
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: A Python Document-Object Mapper for working with MongoDB
|
Summary: A Python Document-Object Mapper for working with MongoDB
|
||||||
|
|
||||||
|
@ -491,7 +491,7 @@ class IndexesTest(unittest.TestCase):
|
|||||||
|
|
||||||
def invalid_index_2():
|
def invalid_index_2():
|
||||||
return BlogPost.objects.hint(('tags', 1))
|
return BlogPost.objects.hint(('tags', 1))
|
||||||
self.assertRaises(TypeError, invalid_index_2)
|
self.assertRaises(Exception, invalid_index_2)
|
||||||
|
|
||||||
def test_unique(self):
|
def test_unique(self):
|
||||||
"""Ensure that uniqueness constraints are applied to fields.
|
"""Ensure that uniqueness constraints are applied to fields.
|
||||||
|
@ -409,6 +409,27 @@ class InstanceTest(unittest.TestCase):
|
|||||||
self.assertEqual(len(doc.embedded_field.list_field), 4)
|
self.assertEqual(len(doc.embedded_field.list_field), 4)
|
||||||
self.assertEqual(len(doc.embedded_field.dict_field), 2)
|
self.assertEqual(len(doc.embedded_field.dict_field), 2)
|
||||||
|
|
||||||
|
def test_reload_doesnt_exist(self):
|
||||||
|
class Foo(Document):
|
||||||
|
pass
|
||||||
|
|
||||||
|
f = Foo()
|
||||||
|
try:
|
||||||
|
f.reload()
|
||||||
|
except Foo.DoesNotExist:
|
||||||
|
pass
|
||||||
|
except Exception as ex:
|
||||||
|
self.assertFalse("Threw wrong exception")
|
||||||
|
|
||||||
|
f.save()
|
||||||
|
f.delete()
|
||||||
|
try:
|
||||||
|
f.reload()
|
||||||
|
except Foo.DoesNotExist:
|
||||||
|
pass
|
||||||
|
except Exception as ex:
|
||||||
|
self.assertFalse("Threw wrong exception")
|
||||||
|
|
||||||
def test_dictionary_access(self):
|
def test_dictionary_access(self):
|
||||||
"""Ensure that dictionary-style field access works properly.
|
"""Ensure that dictionary-style field access works properly.
|
||||||
"""
|
"""
|
||||||
|
@ -16,6 +16,7 @@ settings.configure(
|
|||||||
USE_TZ=True,
|
USE_TZ=True,
|
||||||
INSTALLED_APPS=('django.contrib.auth', 'mongoengine.django.mongo_auth'),
|
INSTALLED_APPS=('django.contrib.auth', 'mongoengine.django.mongo_auth'),
|
||||||
AUTH_USER_MODEL=('mongo_auth.MongoUser'),
|
AUTH_USER_MODEL=('mongo_auth.MongoUser'),
|
||||||
|
AUTHENTICATION_BACKENDS = ('mongoengine.django.auth.MongoEngineBackend',)
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user