From 3c78757778551bfe28495e3630b3e6b991e2a86f Mon Sep 17 00:00:00 2001 From: Benoit Louy Date: Tue, 26 Feb 2013 09:55:29 -0500 Subject: [PATCH 01/23] fix travis build: builds were failing because libz.so location changed. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 550cc6cd..2dc88941 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ env: - PYMONGO=2.3 install: - if [[ $TRAVIS_PYTHON_VERSION == '2.'* ]]; then sudo apt-get install zlib1g zlib1g-dev; fi - - if [[ $TRAVIS_PYTHON_VERSION == '2.'* ]]; then sudo ln -s /usr/lib/i386-linux-gnu/libz.so /usr/lib/; fi + - if [[ $TRAVIS_PYTHON_VERSION == '2.'* ]]; then sudo ln -s /usr/lib/x86_64-linux-gnu/libz.so /usr/lib/; fi - if [[ $TRAVIS_PYTHON_VERSION == '2.'* ]]; then pip install PIL --use-mirrors ; true; fi - if [[ $TRAVIS_PYTHON_VERSION == '2.'* ]]; then pip install PIL --use-mirrors ; true; fi - if [[ $PYMONGO == 'dev' ]]; then pip install https://github.com/mongodb/mongo-python-driver/tarball/master; true; fi From 41a698b442881b7f40cef5b3c6954097d0965a10 Mon Sep 17 00:00:00 2001 From: Russ Weeks Date: Tue, 12 Mar 2013 10:28:29 -0700 Subject: [PATCH 02/23] Changed dereference.py to keep tuples as tuples --- mongoengine/dereference.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mongoengine/dereference.py b/mongoengine/dereference.py index 386dbf4b..fcb6d89a 100644 --- a/mongoengine/dereference.py +++ b/mongoengine/dereference.py @@ -171,6 +171,7 @@ class DeReference(object): if not hasattr(items, 'items'): is_list = True + as_tuple = isinstance(items, tuple) iterator = enumerate(items) data = [] else: @@ -205,7 +206,7 @@ class DeReference(object): if instance and name: if is_list: - return BaseList(data, instance, name) + return tuple(data) if as_tuple else BaseList(data, instance, name) return BaseDict(data, instance, name) depth += 1 return data From f9cd8b1841631c693ebf40479d215bee4ed13d30 Mon Sep 17 00:00:00 2001 From: Russ Weeks Date: Tue, 12 Mar 2013 12:45:38 -0700 Subject: [PATCH 03/23] added unit test for dereference patch --- tests/test_dereference.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/test_dereference.py b/tests/test_dereference.py index 0eb891cb..d7438d2f 100644 --- a/tests/test_dereference.py +++ b/tests/test_dereference.py @@ -997,3 +997,34 @@ class FieldTest(unittest.TestCase): msg = Message.objects.get(id=1) self.assertEqual(0, msg.comments[0].id) self.assertEqual(1, msg.comments[1].id) + + def test_tuples_as_tuples(self): + """ + Ensure that tuples remain tuples when they are + inside a ComplexBaseField + """ + from mongoengine.base import BaseField + class EnumField(BaseField): + def __init__(self, **kwargs): + super(EnumField,self).__init__(**kwargs) + + def to_mongo(self, value): + return value + + def to_python(self, value): + return tuple(value) + + class TestDoc(Document): + items = ListField(EnumField()) + + TestDoc.drop_collection() + tuples = [(100,'Testing')] + doc = TestDoc() + doc.items = tuples + doc.save() + x = TestDoc.objects().get() + self.assertTrue(x is not None) + self.assertTrue(len(x.items) == 1) + self.assertTrue(tuple(x.items[0]) in tuples) + self.assertTrue(x.items[0] in tuples) + From a192029901c6c21b3cc949a6221a1090083ebf86 Mon Sep 17 00:00:00 2001 From: Aleksandr Sorokoumov Date: Sat, 16 Mar 2013 16:47:22 +0100 Subject: [PATCH 04/23] ReferenceField query chaining bug fixed. --- mongoengine/queryset.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mongoengine/queryset.py b/mongoengine/queryset.py index bff05fcf..6c61ab9e 100644 --- a/mongoengine/queryset.py +++ b/mongoengine/queryset.py @@ -367,6 +367,10 @@ class QuerySet(object): self._skip = None self._hint = -1 # Using -1 as None is a valid value for hint + def __deepcopy__(self, memo): + """Essential for chained queries with ReferenceFields involved""" + return self.clone() + def clone(self): """Creates a copy of the current :class:`~mongoengine.queryset.QuerySet` @@ -814,7 +818,6 @@ class QuerySet(object): mongo_query['$and'].append(value) else: mongo_query['$and'] = value - return mongo_query def get(self, *q_objs, **query): From f7515cfca80d870728ae5f03535dcedcd2a6a5b1 Mon Sep 17 00:00:00 2001 From: Aleksandr Sorokoumov Date: Mon, 18 Mar 2013 12:22:55 +0100 Subject: [PATCH 05/23] add myself to AUTHORS --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 82a1dfa4..fe62026d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -128,3 +128,4 @@ that much better: * Peter Teichman * Jakub Kot * Jorge Bastida + * Aleksandr Sorokoumov \ No newline at end of file From 165bea5bb97f24c4b06fedfe38ebb3d925052eaa Mon Sep 17 00:00:00 2001 From: Aleksandr Sorokoumov Date: Mon, 18 Mar 2013 12:32:49 +0100 Subject: [PATCH 06/23] QuerySet chaining test was supplemented with ReferenceField chaining test --- tests/test_queryset.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/tests/test_queryset.py b/tests/test_queryset.py index 5234cea2..43bb70bc 100644 --- a/tests/test_queryset.py +++ b/tests/test_queryset.py @@ -232,28 +232,33 @@ class QuerySetTest(unittest.TestCase): def test_chaining(self): class A(Document): - pass + s = StringField() class B(Document): - a = ReferenceField(A) + ref = ReferenceField(A) + boolfield = BooleanField(default=False) A.drop_collection() B.drop_collection() - a1 = A().save() - a2 = A().save() + a1 = A(s="test1").save() + a2 = A(s="test2").save() - B(a=a1).save() + B(ref=a1, boolfield=True).save() # Works - q1 = B.objects.filter(a__in=[a1, a2], a=a1)._query + q1 = B.objects.filter(ref__in=[a1, a2], ref=a1)._query # Doesn't work - q2 = B.objects.filter(a__in=[a1, a2]) - q2 = q2.filter(a=a1)._query - + q2 = B.objects.filter(ref__in=[a1, a2]) + q2 = q2.filter(ref=a1)._query self.assertEqual(q1, q2) + a_objects = A.objects(s='test1') + query = B.objects(ref__in=a_objects) + query = query.filter(boolfield=True) + self.assertEquals(query.count(), 1) + def test_update_write_options(self): """Test that passing write_options works""" From 74f3f4eb158ab5bd980578582af8454b0198577a Mon Sep 17 00:00:00 2001 From: Stefan Wojcik Date: Mon, 1 Apr 2013 16:17:17 -0700 Subject: [PATCH 07/23] more ordering unit tests --- tests/test_queryset.py | 91 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 81 insertions(+), 10 deletions(-) diff --git a/tests/test_queryset.py b/tests/test_queryset.py index 5234cea2..a87611c8 100644 --- a/tests/test_queryset.py +++ b/tests/test_queryset.py @@ -952,6 +952,11 @@ class QuerySetTest(unittest.TestCase): {'attachments.views.extracted': 'no'}]} self.assertEqual(expected, raw_query) + def assertSequence(self, qs, expected): + self.assertEqual(len(qs), len(expected)) + for i in range(len(qs)): + self.assertEqual(qs[i], expected[i]) + def test_ordering(self): """Ensure default ordering is applied and can be overridden. """ @@ -965,10 +970,10 @@ class QuerySetTest(unittest.TestCase): BlogPost.drop_collection() - blog_post_1 = BlogPost(title="Blog Post #1", - published_date=datetime(2010, 1, 5, 0, 0 ,0)) blog_post_2 = BlogPost(title="Blog Post #2", published_date=datetime(2010, 1, 6, 0, 0 ,0)) + blog_post_1 = BlogPost(title="Blog Post #1", + published_date=datetime(2010, 1, 5, 0, 0 ,0)) blog_post_3 = BlogPost(title="Blog Post #3", published_date=datetime(2010, 1, 7, 0, 0 ,0)) @@ -978,14 +983,13 @@ class QuerySetTest(unittest.TestCase): # get the "first" BlogPost using default ordering # from BlogPost.meta.ordering - latest_post = BlogPost.objects.first() - self.assertEqual(latest_post.title, "Blog Post #3") + expected = [blog_post_3, blog_post_2, blog_post_1] + self.assertSequence(BlogPost.objects.all(), expected) # override default ordering, order BlogPosts by "published_date" - first_post = BlogPost.objects.order_by("+published_date").first() - self.assertEqual(first_post.title, "Blog Post #1") - - BlogPost.drop_collection() + qs = BlogPost.objects.order_by("+published_date") + expected = [blog_post_1, blog_post_2, blog_post_3] + self.assertSequence(qs, expected) def test_only(self): """Ensure that QuerySet.only only returns the requested fields. @@ -1921,8 +1925,8 @@ class QuerySetTest(unittest.TestCase): def test_order_by(self): """Ensure that QuerySets may be ordered. """ - self.Person(name="User A", age=20).save() self.Person(name="User B", age=40).save() + self.Person(name="User A", age=20).save() self.Person(name="User C", age=30).save() names = [p.name for p in self.Person.objects.order_by('-age')] @@ -1937,11 +1941,67 @@ class QuerySetTest(unittest.TestCase): ages = [p.age for p in self.Person.objects.order_by('-name')] self.assertEqual(ages, [30, 40, 20]) + def test_order_by_optional(self): + class BlogPost(Document): + title = StringField() + published_date = DateTimeField(required=False) + + BlogPost.drop_collection() + + blog_post_3 = BlogPost(title="Blog Post #3", + published_date=datetime(2010, 1, 6, 0, 0 ,0)) + blog_post_2 = BlogPost(title="Blog Post #2", + published_date=datetime(2010, 1, 5, 0, 0 ,0)) + blog_post_4 = BlogPost(title="Blog Post #4", + published_date=datetime(2010, 1, 7, 0, 0 ,0)) + blog_post_1 = BlogPost(title="Blog Post #1", published_date=None) + + blog_post_3.save() + blog_post_1.save() + blog_post_4.save() + blog_post_2.save() + + expected = [blog_post_1, blog_post_2, blog_post_3, blog_post_4] + self.assertSequence(BlogPost.objects.order_by('published_date'), + expected) + self.assertSequence(BlogPost.objects.order_by('+published_date'), + expected) + + expected.reverse() + self.assertSequence(BlogPost.objects.order_by('-published_date'), + expected) + + def test_order_by_list(self): + class BlogPost(Document): + title = StringField() + published_date = DateTimeField(required=False) + + BlogPost.drop_collection() + + blog_post_1 = BlogPost(title="A", + published_date=datetime(2010, 1, 6, 0, 0 ,0)) + blog_post_2 = BlogPost(title="B", + published_date=datetime(2010, 1, 6, 0, 0 ,0)) + blog_post_3 = BlogPost(title="C", + published_date=datetime(2010, 1, 7, 0, 0 ,0)) + + blog_post_2.save() + blog_post_3.save() + blog_post_1.save() + + qs = BlogPost.objects.order_by('published_date', 'title') + expected = [blog_post_1, blog_post_2, blog_post_3] + self.assertSequence(qs, expected) + + qs = BlogPost.objects.order_by('-published_date', '-title') + expected.reverse() + self.assertSequence(qs, expected) + def test_order_by_chaining(self): """Ensure that an order_by query chains properly and allows .only() """ - self.Person(name="User A", age=20).save() self.Person(name="User B", age=40).save() + self.Person(name="User A", age=20).save() self.Person(name="User C", age=30).save() only_age = self.Person.objects.order_by('-age').only('age') @@ -1953,6 +2013,17 @@ class QuerySetTest(unittest.TestCase): self.assertEqual(names, [None, None, None]) self.assertEqual(ages, [40, 30, 20]) + qs = self.Person.objects.all().limit(10) + qs = qs.order_by('-age') + ages = [p.age for p in qs] + self.assertEqual(ages, [40, 30, 20]) + + qs = self.Person.objects.all().skip(0) + qs = qs.order_by('-age') + ages = [p.age for p in qs] + self.assertEqual(ages, [40, 30, 20]) + + def test_confirm_order_by_reference_wont_work(self): """Ordering by reference is not possible. Use map / reduce.. or denormalise""" From dfabfce01bd91f9104fde9cd1892f9ca58fbe41b Mon Sep 17 00:00:00 2001 From: Stefan Wojcik Date: Mon, 1 Apr 2013 17:17:01 -0700 Subject: [PATCH 08/23] show that order_by followed by limit works, but not the other way around --- tests/test_queryset.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/test_queryset.py b/tests/test_queryset.py index a87611c8..56177ec4 100644 --- a/tests/test_queryset.py +++ b/tests/test_queryset.py @@ -2013,6 +2013,11 @@ class QuerySetTest(unittest.TestCase): self.assertEqual(names, [None, None, None]) self.assertEqual(ages, [40, 30, 20]) + qs = self.Person.objects.all().order_by('-age') + qs = qs.limit(10) + ages = [p.age for p in qs] + self.assertEqual(ages, [40, 30, 20]) + qs = self.Person.objects.all().limit(10) qs = qs.order_by('-age') ages = [p.age for p in qs] @@ -2023,7 +2028,6 @@ class QuerySetTest(unittest.TestCase): ages = [p.age for p in qs] self.assertEqual(ages, [40, 30, 20]) - def test_confirm_order_by_reference_wont_work(self): """Ordering by reference is not possible. Use map / reduce.. or denormalise""" From dd006a502eede24bad93361c74d6239fc3be4998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristinn=20O=CC=88rn=20Sigur=C3=B0sson?= Date: Thu, 4 Apr 2013 17:09:05 +0200 Subject: [PATCH 09/23] Don't run unset on IntField if the value is 0 (zero). --- mongoengine/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mongoengine/base.py b/mongoengine/base.py index f73af4cc..c2d74f3d 100644 --- a/mongoengine/base.py +++ b/mongoengine/base.py @@ -1207,7 +1207,7 @@ class BaseDocument(object): # Determine if any changed items were actually unset. for path, value in set_data.items(): - if value or isinstance(value, bool): + if value or isinstance(value, bool) or isinstance(value, int): continue # If we've set a value that ain't the default value dont unset it. From 47df8deb58add4a7b93dedcc9da61be0be722d0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristinn=20O=CC=88rn=20Sigur=C3=B0sson?= Date: Thu, 4 Apr 2013 17:30:21 +0200 Subject: [PATCH 10/23] Fix the implementation. --- mongoengine/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mongoengine/base.py b/mongoengine/base.py index c2d74f3d..42091568 100644 --- a/mongoengine/base.py +++ b/mongoengine/base.py @@ -1207,7 +1207,7 @@ class BaseDocument(object): # Determine if any changed items were actually unset. for path, value in set_data.items(): - if value or isinstance(value, bool) or isinstance(value, int): + if value or type(value) in [bool, int]: continue # If we've set a value that ain't the default value dont unset it. From 7e980a16d088d6b73f7e3e6b4bdb3e5b75bd759b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristinn=20O=CC=88rn=20Sigur=C3=B0sson?= Date: Fri, 5 Apr 2013 11:01:46 +0200 Subject: [PATCH 11/23] Don't run unset on IntField if the value is 0 (zero). The IntField in unset if the IntField value doesn't validate to "truthify" (therefore, is set as 0) and the default value of the IntField in question is 0. This is not a logical functionality in my opinion. Take this example. You have an IntField that is a counter which can be incremented and decremented. This counter has the default value of 0 and is a required field. Every time the counter reaches 0, the field is unset. --- mongoengine/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mongoengine/base.py b/mongoengine/base.py index 42091568..fa6f825f 100644 --- a/mongoengine/base.py +++ b/mongoengine/base.py @@ -1207,7 +1207,7 @@ class BaseDocument(object): # Determine if any changed items were actually unset. for path, value in set_data.items(): - if value or type(value) in [bool, int]: + if value or isinstance(value, (bool, int)): continue # If we've set a value that ain't the default value dont unset it. From e9ff655b0ea1941837d3b9b155f530a023be81d1 Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Thu, 11 Apr 2013 14:58:42 +0000 Subject: [PATCH 12/23] Trying to fix travis --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2dc88941..a85aac40 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,8 +14,7 @@ env: install: - if [[ $TRAVIS_PYTHON_VERSION == '2.'* ]]; then sudo apt-get install zlib1g zlib1g-dev; fi - if [[ $TRAVIS_PYTHON_VERSION == '2.'* ]]; then sudo ln -s /usr/lib/x86_64-linux-gnu/libz.so /usr/lib/; fi - - if [[ $TRAVIS_PYTHON_VERSION == '2.'* ]]; then pip install PIL --use-mirrors ; true; fi - - if [[ $TRAVIS_PYTHON_VERSION == '2.'* ]]; then pip install PIL --use-mirrors ; true; fi + - if [[ $TRAVIS_PYTHON_VERSION == '2.'* ]]; then pip install pillow --use-mirrors ; true; fi - if [[ $PYMONGO == 'dev' ]]; then pip install https://github.com/mongodb/mongo-python-driver/tarball/master; true; fi - if [[ $PYMONGO != 'dev' ]]; then pip install pymongo==$PYMONGO --use-mirrors; true; fi - python setup.py install From d9b8ee7895b4c0539a134e998dc6a756da502548 Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Thu, 11 Apr 2013 15:47:53 +0000 Subject: [PATCH 13/23] next test --- .travis.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index a85aac40..5e20e65f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,9 +12,8 @@ env: - PYMONGO=2.4.1 - PYMONGO=2.3 install: - - if [[ $TRAVIS_PYTHON_VERSION == '2.'* ]]; then sudo apt-get install zlib1g zlib1g-dev; fi - - if [[ $TRAVIS_PYTHON_VERSION == '2.'* ]]; then sudo ln -s /usr/lib/x86_64-linux-gnu/libz.so /usr/lib/; fi - - if [[ $TRAVIS_PYTHON_VERSION == '2.'* ]]; then pip install pillow --use-mirrors ; true; fi + - if [[ $TRAVIS_PYTHON_VERSION == '2.'* ]]; then cp /usr/lib/*/libz.so $VIRTUAL_ENV/lib/; fi + - if [[ $TRAVIS_PYTHON_VERSION == '2.'* ]]; then pip install pil --use-mirrors ; true; fi - if [[ $PYMONGO == 'dev' ]]; then pip install https://github.com/mongodb/mongo-python-driver/tarball/master; true; fi - if [[ $PYMONGO != 'dev' ]]; then pip install pymongo==$PYMONGO --use-mirrors; true; fi - python setup.py install @@ -26,3 +25,8 @@ branches: only: - master - "0.8" +# # Get development headers for PIL +# before_install: +# - sudo apt-get update -qq +# - sudo apt-get build-dep -qq python-imaging +# - sudo apt-get install libjpeg-dev From b06f9dbf8d8da9b1f68007c9d9fd6e39de30b135 Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Fri, 12 Apr 2013 10:02:55 +0000 Subject: [PATCH 14/23] Travis travis travis --- .travis.yml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5e20e65f..3968166f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ env: - PYMONGO=2.3 install: - if [[ $TRAVIS_PYTHON_VERSION == '2.'* ]]; then cp /usr/lib/*/libz.so $VIRTUAL_ENV/lib/; fi - - if [[ $TRAVIS_PYTHON_VERSION == '2.'* ]]; then pip install pil --use-mirrors ; true; fi + - if [[ $TRAVIS_PYTHON_VERSION == '2.'* ]]; then pip install pillow --use-mirrors ; true; fi - if [[ $PYMONGO == 'dev' ]]; then pip install https://github.com/mongodb/mongo-python-driver/tarball/master; true; fi - if [[ $PYMONGO != 'dev' ]]; then pip install pymongo==$PYMONGO --use-mirrors; true; fi - python setup.py install diff --git a/setup.py b/setup.py index 6d9b51bc..bcdb183c 100644 --- a/setup.py +++ b/setup.py @@ -58,7 +58,7 @@ if sys.version_info[0] == 3: extra_opts['packages'].append("tests") extra_opts['package_data'] = {"tests": ["mongoengine.png"]} else: - extra_opts['tests_require'] = ['nose', 'coverage', 'blinker', 'django>=1.3', 'PIL'] + extra_opts['tests_require'] = ['nose', 'coverage', 'blinker', 'django=1.4.2', 'pillow'] extra_opts['packages'] = find_packages(exclude=('tests',)) setup(name='mongoengine', From cc5b60b004b19922ce2d59b33217059729134fe9 Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Fri, 12 Apr 2013 10:30:52 +0000 Subject: [PATCH 15/23] Updated pymongo versions and pillow wont work --- .travis.yml | 11 +++-------- setup.py | 2 +- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3968166f..7fb55e36 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,11 +9,11 @@ python: - "3.3" env: - PYMONGO=dev - - PYMONGO=2.4.1 - - PYMONGO=2.3 + - PYMONGO=2.5 + - PYMONGO=2.4.2 install: - if [[ $TRAVIS_PYTHON_VERSION == '2.'* ]]; then cp /usr/lib/*/libz.so $VIRTUAL_ENV/lib/; fi - - if [[ $TRAVIS_PYTHON_VERSION == '2.'* ]]; then pip install pillow --use-mirrors ; true; fi + - if [[ $TRAVIS_PYTHON_VERSION == '2.'* ]]; then pip install pil --use-mirrors ; true; fi - if [[ $PYMONGO == 'dev' ]]; then pip install https://github.com/mongodb/mongo-python-driver/tarball/master; true; fi - if [[ $PYMONGO != 'dev' ]]; then pip install pymongo==$PYMONGO --use-mirrors; true; fi - python setup.py install @@ -25,8 +25,3 @@ branches: only: - master - "0.8" -# # Get development headers for PIL -# before_install: -# - sudo apt-get update -qq -# - sudo apt-get build-dep -qq python-imaging -# - sudo apt-get install libjpeg-dev diff --git a/setup.py b/setup.py index bcdb183c..1863df57 100644 --- a/setup.py +++ b/setup.py @@ -58,7 +58,7 @@ if sys.version_info[0] == 3: extra_opts['packages'].append("tests") extra_opts['package_data'] = {"tests": ["mongoengine.png"]} else: - extra_opts['tests_require'] = ['nose', 'coverage', 'blinker', 'django=1.4.2', 'pillow'] + extra_opts['tests_require'] = ['nose', 'coverage', 'blinker', 'django=1.4.2', 'PIL'] extra_opts['packages'] = find_packages(exclude=('tests',)) setup(name='mongoengine', From 19a7372ff9cbf8c192217bf6665794b6d210623b Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Fri, 12 Apr 2013 10:32:50 +0000 Subject: [PATCH 16/23] Fix test_require for Django --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 1863df57..54c2cdca 100644 --- a/setup.py +++ b/setup.py @@ -58,7 +58,7 @@ if sys.version_info[0] == 3: extra_opts['packages'].append("tests") extra_opts['package_data'] = {"tests": ["mongoengine.png"]} else: - extra_opts['tests_require'] = ['nose', 'coverage', 'blinker', 'django=1.4.2', 'PIL'] + extra_opts['tests_require'] = ['nose', 'coverage', 'blinker', 'django==1.4.2', 'PIL'] extra_opts['packages'] = find_packages(exclude=('tests',)) setup(name='mongoengine', From 5f1d5ea056a16d1df76463869d694c2238d13459 Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Fri, 12 Apr 2013 10:35:09 +0000 Subject: [PATCH 17/23] Try and fix wobbly test --- tests/test_all_warnings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_all_warnings.py b/tests/test_all_warnings.py index 7ef1f210..9b090349 100644 --- a/tests/test_all_warnings.py +++ b/tests/test_all_warnings.py @@ -76,7 +76,7 @@ class TestWarnings(unittest.TestCase): p2.parent.name = "Poppa Wilson" p2.save() - self.assertEqual(len(self.warning_list), 1) + self.assertTrue(len(self.warning_list) > 0) if len(self.warning_list) > 1: print self.warning_list warning = self.warning_list[0] From 49a7542b148686b2c4ab43ed1f87195138c651da Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Fri, 12 Apr 2013 12:55:03 +0000 Subject: [PATCH 18/23] Fixing cloning in python 3 --- docs/changelog.rst | 5 +++++ mongoengine/queryset.py | 13 ++++--------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index d93bf13c..7957560f 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -2,6 +2,11 @@ Changelog ========= +Changes in 0.7.10 +================= +- Int fields no longer unset in save when changed to 0 (#272) +- Fixed ReferenceField query chaining bug fixed (#254) + Changes in 0.7.9 ================ - Better fix handling for old style _types diff --git a/mongoengine/queryset.py b/mongoengine/queryset.py index 6c61ab9e..20b18b7e 100644 --- a/mongoengine/queryset.py +++ b/mongoengine/queryset.py @@ -379,8 +379,8 @@ class QuerySet(object): c = self.__class__(self._document, self._collection_obj) copy_props = ('_initial_query', '_query_obj', '_where_clause', - '_loaded_fields', '_ordering', '_snapshot', - '_timeout', '_limit', '_skip', '_slave_okay', '_hint') + '_loaded_fields', '_ordering', '_snapshot', '_timeout', + '_limit', '_skip', '_slave_okay', '_hint') for prop in copy_props: val = getattr(self, prop) @@ -393,16 +393,11 @@ class QuerySet(object): if self._mongo_query is None: self._mongo_query = self._query_obj.to_query(self._document) if self._class_check: - if PY3: - query = SON(self._initial_query.items()) - query.update(self._mongo_query) - self._mongo_query = query - else: - self._mongo_query.update(self._initial_query) + self._mongo_query.update(self._initial_query) return self._mongo_query def ensure_index(self, key_or_list, drop_dups=False, background=False, - **kwargs): + **kwargs): """Ensure that the given indexes are in place. :param key_or_list: a single index key or a list of index keys (to From 836dc96f67a2773671da9844508843242a5d23d6 Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Fri, 12 Apr 2013 12:56:15 +0000 Subject: [PATCH 19/23] Updated changelog --- docs/changelog.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index 7957560f..ccf099fc 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -4,6 +4,7 @@ Changelog Changes in 0.7.10 ================= +- Fixed cloning querysets in PY3 - Int fields no longer unset in save when changed to 0 (#272) - Fixed ReferenceField query chaining bug fixed (#254) From 37740dc01042ec7c8ce60ee365eae591de283032 Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Fri, 12 Apr 2013 14:05:08 +0000 Subject: [PATCH 20/23] Added kwargs to doc.save to help interop with django (#223, #270) --- docs/changelog.rst | 1 + mongoengine/document.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index ccf099fc..8619a635 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -4,6 +4,7 @@ Changelog Changes in 0.7.10 ================= +- Added kwargs to doc.save to help interop with django (#223, #270) - Fixed cloning querysets in PY3 - Int fields no longer unset in save when changed to 0 (#272) - Fixed ReferenceField query chaining bug fixed (#254) diff --git a/mongoengine/document.py b/mongoengine/document.py index 7b3afafb..a251f589 100644 --- a/mongoengine/document.py +++ b/mongoengine/document.py @@ -164,7 +164,7 @@ class Document(BaseDocument): def save(self, safe=True, force_insert=False, validate=True, write_options=None, cascade=None, cascade_kwargs=None, - _refs=None): + _refs=None, **kwargs): """Save the :class:`~mongoengine.Document` to the database. If the document already exists, it will be updated, otherwise it will be created. From 63edd16a925b775251e04bbf362d3540748e138d Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Fri, 12 Apr 2013 14:20:44 +0000 Subject: [PATCH 21/23] Resolve field name to db field name when using distinct(#260, #264, #269) --- AUTHORS | 4 +++- docs/changelog.rst | 1 + mongoengine/queryset.py | 7 +++++-- tests/test_queryset.py | 19 +++++++++++++++++++ 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/AUTHORS b/AUTHORS index fe62026d..9d31c955 100644 --- a/AUTHORS +++ b/AUTHORS @@ -128,4 +128,6 @@ that much better: * Peter Teichman * Jakub Kot * Jorge Bastida - * Aleksandr Sorokoumov \ No newline at end of file + * Aleksandr Sorokoumov + * Yohan Graterol + * bool-dev \ No newline at end of file diff --git a/docs/changelog.rst b/docs/changelog.rst index 8619a635..667413e2 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -4,6 +4,7 @@ Changelog Changes in 0.7.10 ================= +- Resolve field name to db field name when using distinct(#260, #264, #269) - Added kwargs to doc.save to help interop with django (#223, #270) - Fixed cloning querysets in PY3 - Int fields no longer unset in save when changed to 0 (#272) diff --git a/mongoengine/queryset.py b/mongoengine/queryset.py index 20b18b7e..4aeff833 100644 --- a/mongoengine/queryset.py +++ b/mongoengine/queryset.py @@ -1212,8 +1212,11 @@ class QuerySet(object): .. versionchanged:: 0.5 - Fixed handling references .. versionchanged:: 0.6 - Improved db_field refrence handling """ - return self._dereference(self._cursor.distinct(field), 1, - name=field, instance=self._document) + try: + field = self._fields_to_dbfields([field]).pop() + finally: + return self._dereference(self._cursor.distinct(field), 1, + name=field, instance=self._document) def only(self, *fields): """Load only a subset of this document's fields. :: diff --git a/tests/test_queryset.py b/tests/test_queryset.py index 43bb70bc..88daa5fa 100644 --- a/tests/test_queryset.py +++ b/tests/test_queryset.py @@ -2486,6 +2486,25 @@ class QuerySetTest(unittest.TestCase): self.assertEqual(Foo.objects.distinct("bar"), [bar]) + def test_distinct_handles_db_field(self): + """Ensure that distinct resolves field name to db_field as expected. + """ + class Product(Document): + product_id = IntField(db_field='pid') + + Product.drop_collection() + + Product(product_id=1).save() + Product(product_id=2).save() + Product(product_id=1).save() + + self.assertEqual(set(Product.objects.distinct('product_id')), + set([1, 2])) + self.assertEqual(set(Product.objects.distinct('pid')), + set([1, 2])) + + Product.drop_collection() + def test_custom_manager(self): """Ensure that custom QuerySetManager instances work as expected. """ From 2f19b22bb227097beabbc37ef5abcd86bb621074 Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Fri, 12 Apr 2013 14:25:43 +0000 Subject: [PATCH 22/23] Added dereference support for tuples (#250) --- AUTHORS | 3 ++- docs/changelog.rst | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 9d31c955..aeb672cb 100644 --- a/AUTHORS +++ b/AUTHORS @@ -130,4 +130,5 @@ that much better: * Jorge Bastida * Aleksandr Sorokoumov * Yohan Graterol - * bool-dev \ No newline at end of file + * bool-dev + * Russ Weeks \ No newline at end of file diff --git a/docs/changelog.rst b/docs/changelog.rst index 667413e2..5ecae628 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -4,6 +4,7 @@ Changelog Changes in 0.7.10 ================= +- Added dereference support for tuples (#250) - Resolve field name to db field name when using distinct(#260, #264, #269) - Added kwargs to doc.save to help interop with django (#223, #270) - Fixed cloning querysets in PY3 From c9a5710554cca690f6ee2a574d03be05d93a3e78 Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Fri, 12 Apr 2013 15:56:40 +0000 Subject: [PATCH 23/23] Fixed order_by chaining issue (#265) --- docs/changelog.rst | 1 + mongoengine/queryset.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 5ecae628..65a5aaf1 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -4,6 +4,7 @@ Changelog Changes in 0.7.10 ================= +- Fixed order_by chaining issue (#265) - Added dereference support for tuples (#250) - Resolve field name to db field name when using distinct(#260, #264, #269) - Added kwargs to doc.save to help interop with django (#223, #270) diff --git a/mongoengine/queryset.py b/mongoengine/queryset.py index 4aeff833..727f56ea 100644 --- a/mongoengine/queryset.py +++ b/mongoengine/queryset.py @@ -1321,7 +1321,8 @@ class QuerySet(object): key_list.append((key, direction)) self._ordering = key_list - + if self._cursor_obj: + self._cursor_obj.sort(key_list) return self def explain(self, format=False):