From 5bbfca45fa1017e58b2d6c1413ee963261462b3f Mon Sep 17 00:00:00 2001 From: Gang Li Date: Mon, 12 Oct 2015 10:34:26 -0400 Subject: [PATCH 1/7] Fixed: ListField minus index assignment does not work #1119 Add code to detect '-1' as a integer. Normalize negative index to regular list index Added list assignment test case --- mongoengine/base/document.py | 8 ++++-- tests/fields/fields.py | 48 ++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/mongoengine/base/document.py b/mongoengine/base/document.py index 6353162a..64bf24a4 100644 --- a/mongoengine/base/document.py +++ b/mongoengine/base/document.py @@ -606,7 +606,9 @@ class BaseDocument(object): for p in parts: if isinstance(d, (ObjectId, DBRef)): break - elif isinstance(d, list) and p.isdigit(): + elif isinstance(d, list) and p.lstrip('-').isdigit(): + if p[0] == '-': + p = str(len(d)+int(p)) try: d = d[int(p)] except IndexError: @@ -640,7 +642,9 @@ class BaseDocument(object): parts = path.split('.') db_field_name = parts.pop() for p in parts: - if isinstance(d, list) and p.isdigit(): + if isinstance(d, list) and p.lstrip('-').isdigit(): + if p[0] == '-': + p = str(len(d)+int(p)) d = d[int(p)] elif (hasattr(d, '__getattribute__') and not isinstance(d, dict)): diff --git a/tests/fields/fields.py b/tests/fields/fields.py index 7ef298fc..0089f60d 100644 --- a/tests/fields/fields.py +++ b/tests/fields/fields.py @@ -1022,6 +1022,54 @@ class FieldTest(unittest.TestCase): self.assertEqual(BlogPost.objects(info=['1', '2', '3', '4', '1', '2', '3', '4']).count(), 1) BlogPost.drop_collection() + def test_list_assignment(self): + """Ensure that list field element assignment and slicing work + """ + class BlogPost(Document): + info = ListField() + + BlogPost.drop_collection() + + post = BlogPost() + post.info = ['e1', 'e2', 3, '4', 5] + post.save() + + post.info[0] = 1 + post.save() + post.reload() + self.assertEqual(post.info[0], 1) + + post.info[1:3] = ['n2', 'n3'] + post.save() + post.reload() + self.assertEqual(post.info, [1, 'n2', 'n3', '4', 5]) + + post.info[-1] = 'n5' + post.save() + post.reload() + self.assertEqual(post.info, [1, 'n2', 'n3', '4', 'n5']) + + post.info[-2] = 4 + post.save() + post.reload() + self.assertEqual(post.info, [1, 'n2', 'n3', 4, 'n5']) + + post.info[1:-1] = [2] + post.save() + post.reload() + self.assertEqual(post.info, [1, 2, 'n5']) + + post.info[:-1] = [1, 'n2', 'n3', 4] + post.save() + post.reload() + self.assertEqual(post.info, [1, 'n2', 'n3', 4, 'n5']) + + post.info[-4:3] = [2, 3] + post.save() + post.reload() + self.assertEqual(post.info, [1, 2, 3, 4, 'n5']) + + def test_list_field_passed_in_value(self): class Foo(Document): bars = ListField(ReferenceField("Bar")) From eb8176971c31591df4a7ab9f8f61efdb25e2dd68 Mon Sep 17 00:00:00 2001 From: Gang Li Date: Mon, 12 Oct 2015 23:33:54 -0400 Subject: [PATCH 2/7] Removed "elif field.default" block to avoid silently, inconsistently changing database This resolved issue Please recall fix on: Saving document doesn't create new fields in existing collection #620 #1126 --- mongoengine/base/document.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/mongoengine/base/document.py b/mongoengine/base/document.py index 64bf24a4..f8dd8400 100644 --- a/mongoengine/base/document.py +++ b/mongoengine/base/document.py @@ -712,14 +712,6 @@ class BaseDocument(object): del data[field.db_field] except (AttributeError, ValueError), e: errors_dict[field_name] = e - elif field.default: - default = field.default - if callable(default): - default = default() - if isinstance(default, BaseDocument): - changed_fields.append(field_name) - elif not only_fields or field_name in only_fields: - changed_fields.append(field_name) if errors_dict: errors = "\n".join(["%s - %s" % (k, v) From 3fe93968a6d428a94ca70cca4a39d090ff5e10f7 Mon Sep 17 00:00:00 2001 From: Gang Li Date: Sun, 18 Oct 2015 00:19:36 -0400 Subject: [PATCH 3/7] update test case for: Please recall fix on: Saving document doesn't create new fields in existing collection #620 #1126 --- tests/document/instance.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/document/instance.py b/tests/document/instance.py index 7a393416..3d41857e 100644 --- a/tests/document/instance.py +++ b/tests/document/instance.py @@ -2941,6 +2941,17 @@ class InstanceTest(unittest.TestCase): p4 = Person.objects()[0] p4.save() self.assertEquals(p4.height, 189) + + # However the default will not be fixed in DB + self.assertEquals(Person.objects(height=189).count(), 0) + + # alter DB for the new default + coll = Person._get_collection() + for person in Person.objects.as_pymongo(): + if 'height' not in person: + person['height'] = 189 + coll.save(person) + self.assertEquals(Person.objects(height=189).count(), 1) def test_from_son(self): From 2ae2bfdde937b0f28b0598aa29d9fcd8d6c6e40c Mon Sep 17 00:00:00 2001 From: Gang Li Date: Sun, 18 Oct 2015 00:31:40 -0400 Subject: [PATCH 4/7] updated changelog.rst for #1119 --- AUTHORS | 27 ++++++++++++++------------- docs/changelog.rst | 2 ++ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/AUTHORS b/AUTHORS index a66bf7c0..a371f816 100644 --- a/AUTHORS +++ b/AUTHORS @@ -6,7 +6,7 @@ Matt Dennewitz Deepak Thukral Florian Schlachter Steve Challis -Wilson Júnior +Wilson Júnior Dan Crosta https://github.com/dcrosta Laine Herron https://github.com/LaineHerron @@ -23,7 +23,7 @@ that much better: * flosch * Deepak Thukral * Colin Howe - * Wilson Júnior (https://github.com/wpjunior) + * Wilson Júnior (https://github.com/wpjunior) * Alistair Roche * Dan Crosta * Viktor Kerkez @@ -34,7 +34,7 @@ that much better: * Mircea Pasoi * Matt Chisholm * James Punteney - * TimothéePeignier + * TimothéePeignier * Stuart Rackham * Serge Matveenko * Matt Dennewitz @@ -46,7 +46,7 @@ that much better: * Nick Vlku * martin * Flavio Amieiro - * Анхбаяр Лхагвадорж + * Ð�нхбаÑ�Ñ€ Лхагвадорж * Zak Johnson * Victor Farazdagi * vandersonmota @@ -75,7 +75,7 @@ that much better: * Adam Parrish * jpfarias * jonrscott - * Alice Zoë Bevan-McGregor (https://github.com/amcgregor/) + * Alice Zoë Bevan-McGregor (https://github.com/amcgregor/) * Stephen Young * tkloc * aid @@ -111,7 +111,7 @@ that much better: * Tristan Escalada * Alexander Koshelev * Jaime Irurzun - * Alexandre González + * Alexandre González * Thomas Steinacher * Tommi Komulainen * Peter Landry @@ -119,7 +119,7 @@ that much better: * Anton Kolechkin * Sergey Nikitin * psychogenic - * Stefan Wójcik (https://github.com/wojcikstefan) + * Stefan Wójcik (https://github.com/wojcikstefan) * dimonb * Garry Polley * James Slagle @@ -147,7 +147,7 @@ that much better: * Gustavo Gawryszewski * Max Countryman * caitifbrito - * lcya86 刘春洋 + * lcya86 刘春洋 * Martin Alderete (https://github.com/malderete) * Nick Joyce * Jared Forsyth @@ -174,7 +174,7 @@ that much better: * Paul Uithol (https://github.com/PaulUithol) * Thom Knowles (https://github.com/fleat) * Paul (https://github.com/squamous) - * Olivier Cortès (https://github.com/Karmak23) + * Olivier Cortès (https://github.com/Karmak23) * crazyzubr (https://github.com/crazyzubr) * FrankSomething (https://github.com/FrankSomething) * Alexandr Morozov (https://github.com/LK4D4) @@ -183,7 +183,7 @@ that much better: * Daniel Ward (https://github.com/danielward) * Aniket Deshpande (https://github.com/anicake) * rfkrocktk (https://github.com/rfkrocktk) - * Gustavo Andrés Angulo (https://github.com/woakas) + * Gustavo Andrés Angulo (https://github.com/woakas) * Dmytro Popovych (https://github.com/drudim) * Tom (https://github.com/tomprimozic) * j0hnsmith (https://github.com/j0hnsmith) @@ -198,7 +198,7 @@ that much better: * Martyn Smith (https://github.com/martynsmith) * Andrei Zbikowski (https://github.com/b1naryth1ef) * Ronald van Rij (https://github.com/ronaldvanrij) - * François Schmidts (https://github.com/jaesivsm) + * François Schmidts (https://github.com/jaesivsm) * Eric Plumb (https://github.com/professorplumb) * Damien Churchill (https://github.com/damoxc) * Aleksandr Sorokoumov (https://github.com/Gerrrr) @@ -211,12 +211,12 @@ that much better: * Axel Haustant (https://github.com/noirbizarre) * David Czarnecki (https://github.com/czarneckid) * Vyacheslav Murashkin (https://github.com/a4tunado) - * André Ericson https://github.com/aericson) + * André Ericson https://github.com/aericson) * Mikhail Moshnogorsky (https://github.com/mikhailmoshnogorsky) * Diego Berrocal (https://github.com/cestdiego) * Matthew Ellison (https://github.com/seglberg) * Jimmy Shen (https://github.com/jimmyshen) - * J. Fernando Sánchez (https://github.com/balkian) + * J. Fernando Sánchez (https://github.com/balkian) * Michael Chase (https://github.com/rxsegrxup) * Eremeev Danil (https://github.com/elephanter) * Catstyle Lee (https://github.com/Catstyle) @@ -228,3 +228,4 @@ that much better: * Vicki Donchenko (https://github.com/kivistein) * Emile Caron (https://github.com/emilecaron) * Amit Lichtenberg (https://github.com/amitlicht) + * Gang Li (https://github.com/iici-gli) diff --git a/docs/changelog.rst b/docs/changelog.rst index 4e9dea58..fd06f6e9 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -10,6 +10,8 @@ Changes in 0.10.1 - DEV - Document save's save_condition error raises `SaveConditionError` exception #1070 - Fix Document.reload for DynamicDocument. #1050 - StrictDict & SemiStrictDict are shadowed at init time. #1105 +- Fix ListField minus index assignment does not work. #1119 +- Remove code that marks field as changed when the field has default but not existed in database #1126 Changes in 0.10.0 ================= From c1645ab7a7f6b1dbc3107e25024f6cc4c65e6fd2 Mon Sep 17 00:00:00 2001 From: Gang Li Date: Sun, 18 Oct 2015 01:14:27 -0400 Subject: [PATCH 5/7] restored --- AUTHORS | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/AUTHORS b/AUTHORS index a371f816..12ae9ff6 100644 --- a/AUTHORS +++ b/AUTHORS @@ -6,7 +6,7 @@ Matt Dennewitz Deepak Thukral Florian Schlachter Steve Challis -Wilson Júnior +Wilson Júnior Dan Crosta https://github.com/dcrosta Laine Herron https://github.com/LaineHerron @@ -23,7 +23,7 @@ that much better: * flosch * Deepak Thukral * Colin Howe - * Wilson Júnior (https://github.com/wpjunior) + * Wilson Júnior (https://github.com/wpjunior) * Alistair Roche * Dan Crosta * Viktor Kerkez @@ -34,7 +34,7 @@ that much better: * Mircea Pasoi * Matt Chisholm * James Punteney - * TimothéePeignier + * TimothéePeignier * Stuart Rackham * Serge Matveenko * Matt Dennewitz @@ -46,7 +46,7 @@ that much better: * Nick Vlku * martin * Flavio Amieiro - * Ð�нхбаÑ�Ñ€ Лхагвадорж + * Анхбаяр Лхагвадорж * Zak Johnson * Victor Farazdagi * vandersonmota @@ -75,7 +75,7 @@ that much better: * Adam Parrish * jpfarias * jonrscott - * Alice Zoë Bevan-McGregor (https://github.com/amcgregor/) + * Alice Zoë Bevan-McGregor (https://github.com/amcgregor/) * Stephen Young * tkloc * aid @@ -111,7 +111,7 @@ that much better: * Tristan Escalada * Alexander Koshelev * Jaime Irurzun - * Alexandre González + * Alexandre González * Thomas Steinacher * Tommi Komulainen * Peter Landry @@ -119,7 +119,7 @@ that much better: * Anton Kolechkin * Sergey Nikitin * psychogenic - * Stefan Wójcik (https://github.com/wojcikstefan) + * Stefan Wójcik (https://github.com/wojcikstefan) * dimonb * Garry Polley * James Slagle @@ -147,7 +147,7 @@ that much better: * Gustavo Gawryszewski * Max Countryman * caitifbrito - * lcya86 刘春洋 + * lcya86 刘春洋 * Martin Alderete (https://github.com/malderete) * Nick Joyce * Jared Forsyth @@ -174,7 +174,7 @@ that much better: * Paul Uithol (https://github.com/PaulUithol) * Thom Knowles (https://github.com/fleat) * Paul (https://github.com/squamous) - * Olivier Cortès (https://github.com/Karmak23) + * Olivier Cortès (https://github.com/Karmak23) * crazyzubr (https://github.com/crazyzubr) * FrankSomething (https://github.com/FrankSomething) * Alexandr Morozov (https://github.com/LK4D4) @@ -183,7 +183,7 @@ that much better: * Daniel Ward (https://github.com/danielward) * Aniket Deshpande (https://github.com/anicake) * rfkrocktk (https://github.com/rfkrocktk) - * Gustavo Andrés Angulo (https://github.com/woakas) + * Gustavo Andrés Angulo (https://github.com/woakas) * Dmytro Popovych (https://github.com/drudim) * Tom (https://github.com/tomprimozic) * j0hnsmith (https://github.com/j0hnsmith) @@ -198,7 +198,7 @@ that much better: * Martyn Smith (https://github.com/martynsmith) * Andrei Zbikowski (https://github.com/b1naryth1ef) * Ronald van Rij (https://github.com/ronaldvanrij) - * François Schmidts (https://github.com/jaesivsm) + * François Schmidts (https://github.com/jaesivsm) * Eric Plumb (https://github.com/professorplumb) * Damien Churchill (https://github.com/damoxc) * Aleksandr Sorokoumov (https://github.com/Gerrrr) @@ -211,12 +211,12 @@ that much better: * Axel Haustant (https://github.com/noirbizarre) * David Czarnecki (https://github.com/czarneckid) * Vyacheslav Murashkin (https://github.com/a4tunado) - * André Ericson https://github.com/aericson) + * André Ericson https://github.com/aericson) * Mikhail Moshnogorsky (https://github.com/mikhailmoshnogorsky) * Diego Berrocal (https://github.com/cestdiego) * Matthew Ellison (https://github.com/seglberg) * Jimmy Shen (https://github.com/jimmyshen) - * J. Fernando Sánchez (https://github.com/balkian) + * J. Fernando Sánchez (https://github.com/balkian) * Michael Chase (https://github.com/rxsegrxup) * Eremeev Danil (https://github.com/elephanter) * Catstyle Lee (https://github.com/Catstyle) From ca415d5d623b47bfd7e765b28c0b1778db0bbe3b Mon Sep 17 00:00:00 2001 From: Gang Li Date: Sun, 4 Sep 2016 14:20:59 -0400 Subject: [PATCH 6/7] Fix for:Base document _mark_as_changed bug #1369 --- mongoengine/base/document.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mongoengine/base/document.py b/mongoengine/base/document.py index f8dd8400..12d3dfa0 100644 --- a/mongoengine/base/document.py +++ b/mongoengine/base/document.py @@ -491,7 +491,7 @@ class BaseDocument(object): # remove lower level changed fields level = '.'.join(levels[:idx]) + '.' remove = self._changed_fields.remove - for field in self._changed_fields: + for field in self._changed_fields[:]: if field.startswith(level): remove(field) From 2c4536e13756c0388fff25d6445e664c354b31e6 Mon Sep 17 00:00:00 2001 From: Gang Li Date: Tue, 6 Sep 2016 17:27:47 -0400 Subject: [PATCH 7/7] redo fix for ListField loses use_db_field when serializing #1217 The new fix reverted the change on BaseField to_mongo so that it will not force new field class to add kwargs to to_mongo function. The new derived field class to_mongo can support use_db_field and fields parameters as needed. Basically all field classes derived from ComplexBaseField support those parameters. --- mongoengine/base/document.py | 16 ++++++----- mongoengine/base/fields.py | 35 +++++++++++++++--------- mongoengine/fields.py | 52 +++++++++++++++++++----------------- tests/fields/fields.py | 2 +- 4 files changed, 61 insertions(+), 44 deletions(-) diff --git a/mongoengine/base/document.py b/mongoengine/base/document.py index 4959991e..d9f59ada 100644 --- a/mongoengine/base/document.py +++ b/mongoengine/base/document.py @@ -309,7 +309,7 @@ class BaseDocument(object): data = SON() data["_id"] = None data['_cls'] = self._class_name - EmbeddedDocumentField = _import_class("EmbeddedDocumentField") + # only root fields ['test1.a', 'test2'] => ['test1', 'test2'] root_fields = set([f.split('.')[0] for f in fields]) @@ -324,18 +324,20 @@ class BaseDocument(object): field = self._dynamic_fields.get(field_name) if value is not None: - - if fields: + f_inputs = field.to_mongo.__code__.co_varnames + ex_vars = {} + if fields and 'fields' in f_inputs: key = '%s.' % field_name embedded_fields = [ i.replace(key, '') for i in fields if i.startswith(key)] - else: - embedded_fields = [] + ex_vars['fields'] = embedded_fields - value = field.to_mongo(value, use_db_field=use_db_field, - fields=embedded_fields) + if 'use_db_field' in f_inputs: + ex_vars['use_db_field'] = use_db_field + + value = field.to_mongo(value, **ex_vars) # Handle self generating fields if value is None and field._auto_gen: diff --git a/mongoengine/base/fields.py b/mongoengine/base/fields.py index a803657d..ce30bfa7 100644 --- a/mongoengine/base/fields.py +++ b/mongoengine/base/fields.py @@ -158,11 +158,24 @@ class BaseField(object): """ return value - def to_mongo(self, value, **kwargs): + def to_mongo(self, value): """Convert a Python type to a MongoDB-compatible type. """ return self.to_python(value) + def _to_mongo_safe_call(self, value, use_db_field=True, fields=None): + """A helper method to call to_mongo with proper inputs + """ + f_inputs = self.to_mongo.__code__.co_varnames + ex_vars = {} + if 'fields' in f_inputs: + ex_vars['fields'] = fields + + if 'use_db_field' in f_inputs: + ex_vars['use_db_field'] = use_db_field + + return self.to_mongo(value, **ex_vars) + def prepare_query_value(self, op, value): """Prepare a value that is being used in a query for PyMongo. """ @@ -324,7 +337,7 @@ class ComplexBaseField(BaseField): key=operator.itemgetter(0))] return value_dict - def to_mongo(self, value, **kwargs): + def to_mongo(self, value, use_db_field=True, fields=None): """Convert a Python type to a MongoDB-compatible type. """ Document = _import_class("Document") @@ -336,10 +349,9 @@ class ComplexBaseField(BaseField): if hasattr(value, 'to_mongo'): if isinstance(value, Document): - return GenericReferenceField().to_mongo( - value, **kwargs) + return GenericReferenceField().to_mongo(value) cls = value.__class__ - val = value.to_mongo(**kwargs) + val = value.to_mongo(use_db_field, fields) # If it's a document that is not inherited add _cls if isinstance(value, EmbeddedDocument): val['_cls'] = cls.__name__ @@ -354,7 +366,7 @@ class ComplexBaseField(BaseField): return value if self.field: - value_dict = dict([(key, self.field.to_mongo(item, **kwargs)) + value_dict = dict([(key, self.field._to_mongo_safe_call(item, use_db_field, fields)) for key, item in value.iteritems()]) else: value_dict = {} @@ -373,20 +385,19 @@ class ComplexBaseField(BaseField): meta.get('allow_inheritance', ALLOW_INHERITANCE) is True) if not allow_inheritance and not self.field: - value_dict[k] = GenericReferenceField().to_mongo( - v, **kwargs) + value_dict[k] = GenericReferenceField().to_mongo(v) else: collection = v._get_collection_name() value_dict[k] = DBRef(collection, v.pk) elif hasattr(v, 'to_mongo'): cls = v.__class__ - val = v.to_mongo(**kwargs) + val = v.to_mongo(use_db_field, fields) # If it's a document that is not inherited add _cls if isinstance(v, (Document, EmbeddedDocument)): val['_cls'] = cls.__name__ value_dict[k] = val else: - value_dict[k] = self.to_mongo(v, **kwargs) + value_dict[k] = self.to_mongo(v, use_db_field, fields) if is_list: # Convert back to a list return [v for _, v in sorted(value_dict.items(), @@ -444,7 +455,7 @@ class ObjectIdField(BaseField): pass return value - def to_mongo(self, value, **kwargs): + def to_mongo(self, value): if not isinstance(value, ObjectId): try: return ObjectId(unicode(value)) @@ -619,7 +630,7 @@ class GeoJsonBaseField(BaseField): if errors: return "Invalid MultiPolygon:\n%s" % ", ".join(errors) - def to_mongo(self, value, **kwargs): + def to_mongo(self, value): if isinstance(value, dict): return value return SON([("type", self._type), ("coordinates", value)]) diff --git a/mongoengine/fields.py b/mongoengine/fields.py index 2db6383c..1b85f96e 100644 --- a/mongoengine/fields.py +++ b/mongoengine/fields.py @@ -231,7 +231,7 @@ class LongField(BaseField): pass return value - def to_mongo(self, value, **kwargs): + def to_mongo(self, value): return Int64(value) def validate(self, value): @@ -338,7 +338,7 @@ class DecimalField(BaseField): return value return value.quantize(decimal.Decimal(".%s" % ("0" * self.precision)), rounding=self.rounding) - def to_mongo(self, value, **kwargs): + def to_mongo(self, value): if value is None: return value if self.force_string: @@ -401,7 +401,7 @@ class DateTimeField(BaseField): if not isinstance(new_value, (datetime.datetime, datetime.date)): self.error(u'cannot parse date "%s"' % value) - def to_mongo(self, value, **kwargs): + def to_mongo(self, value): if value is None: return value if isinstance(value, datetime.datetime): @@ -524,7 +524,7 @@ class ComplexDateTimeField(StringField): except Exception: return original_value - def to_mongo(self, value, **kwargs): + def to_mongo(self, value): value = self.to_python(value) return self._convert_from_datetime(value) @@ -559,10 +559,10 @@ class EmbeddedDocumentField(BaseField): return self.document_type._from_son(value, _auto_dereference=self._auto_dereference) return value - def to_mongo(self, value, **kwargs): + def to_mongo(self, value, use_db_field=True, fields=None): if not isinstance(value, self.document_type): return value - return self.document_type.to_mongo(value, **kwargs) + return self.document_type.to_mongo(value, use_db_field, fields) def validate(self, value, clean=True): """Make sure that the document instance is an instance of the @@ -612,11 +612,11 @@ class GenericEmbeddedDocumentField(BaseField): value.validate(clean=clean) - def to_mongo(self, document, **kwargs): + def to_mongo(self, document, use_db_field=True, fields=None): if document is None: return None - data = document.to_mongo(**kwargs) + data = document.to_mongo(use_db_field, fields) if '_cls' not in data: data['_cls'] = document._class_name return data @@ -628,7 +628,7 @@ class DynamicField(BaseField): Used by :class:`~mongoengine.DynamicDocument` to handle dynamic data""" - def to_mongo(self, value, **kwargs): + def to_mongo(self, value, use_db_field=True, fields=None): """Convert a Python type to a MongoDB compatible type. """ @@ -637,7 +637,7 @@ class DynamicField(BaseField): if hasattr(value, 'to_mongo'): cls = value.__class__ - val = value.to_mongo(**kwargs) + val = value.to_mongo(use_db_field, fields) # If we its a document thats not inherited add _cls if isinstance(value, Document): val = {"_ref": value.to_dbref(), "_cls": cls.__name__} @@ -655,7 +655,7 @@ class DynamicField(BaseField): data = {} for k, v in value.iteritems(): - data[k] = self.to_mongo(v, **kwargs) + data[k] = self.to_mongo(v, use_db_field, fields) value = data if is_list: # Convert back to a list @@ -767,8 +767,8 @@ class SortedListField(ListField): self._order_reverse = kwargs.pop('reverse') super(SortedListField, self).__init__(field, **kwargs) - def to_mongo(self, value, **kwargs): - value = super(SortedListField, self).to_mongo(value, **kwargs) + def to_mongo(self, value, use_db_field=True, fields=None): + value = super(SortedListField, self).to_mongo(value, use_db_field, fields) if self._ordering is not None: return sorted(value, key=itemgetter(self._ordering), reverse=self._order_reverse) @@ -954,7 +954,7 @@ class ReferenceField(BaseField): return super(ReferenceField, self).__get__(instance, owner) - def to_mongo(self, document, **kwargs): + def to_mongo(self, document): if isinstance(document, DBRef): if not self.dbref: return document.id @@ -977,7 +977,7 @@ class ReferenceField(BaseField): id_field_name = cls._meta['id_field'] id_field = cls._fields[id_field_name] - id_ = id_field.to_mongo(id_, **kwargs) + id_ = id_field.to_mongo(id_) if self.document_type._meta.get('abstract'): collection = cls._get_collection_name() return DBRef(collection, id_, cls=cls._class_name) @@ -1100,7 +1100,7 @@ class CachedReferenceField(BaseField): return super(CachedReferenceField, self).__get__(instance, owner) - def to_mongo(self, document, **kwargs): + def to_mongo(self, document, use_db_field=True, fields=None): id_field_name = self.document_type._meta['id_field'] id_field = self.document_type._fields[id_field_name] @@ -1115,11 +1115,15 @@ class CachedReferenceField(BaseField): # TODO: should raise here or will fail next statement value = SON(( - ("_id", id_field.to_mongo(id_, **kwargs)), + ("_id", id_field.to_mongo(id_)), )) - kwargs['fields'] = self.fields - value.update(dict(document.to_mongo(**kwargs))) + if fields: + new_fields = [f for f in self.fields if f in fields] + else: + new_fields = self.fields + + value.update(dict(document.to_mongo(use_db_field, fields=new_fields))) return value def prepare_query_value(self, op, value): @@ -1235,7 +1239,7 @@ class GenericReferenceField(BaseField): doc = doc_cls._from_son(doc) return doc - def to_mongo(self, document, **kwargs): + def to_mongo(self, document): if document is None: return None @@ -1254,7 +1258,7 @@ class GenericReferenceField(BaseField): else: id_ = document - id_ = id_field.to_mongo(id_, **kwargs) + id_ = id_field.to_mongo(id_) collection = document._get_collection_name() ref = DBRef(collection, id_) return SON(( @@ -1283,7 +1287,7 @@ class BinaryField(BaseField): value = bin_type(value) return super(BinaryField, self).__set__(instance, value) - def to_mongo(self, value, **kwargs): + def to_mongo(self, value): return Binary(value) def validate(self, value): @@ -1508,7 +1512,7 @@ class FileField(BaseField): db_alias=db_alias, collection_name=collection_name) - def to_mongo(self, value, **kwargs): + def to_mongo(self, value): # Store the GridFS file id in MongoDB if isinstance(value, self.proxy_class) and value.grid_id is not None: return value.grid_id @@ -1858,7 +1862,7 @@ class UUIDField(BaseField): return original_value return value - def to_mongo(self, value, **kwargs): + def to_mongo(self, value): if not self._binary: return unicode(value) elif isinstance(value, basestring): diff --git a/tests/fields/fields.py b/tests/fields/fields.py index ef35874d..3b3fe857 100644 --- a/tests/fields/fields.py +++ b/tests/fields/fields.py @@ -3527,7 +3527,7 @@ class FieldTest(unittest.TestCase): def __init__(self, **kwargs): super(EnumField, self).__init__(**kwargs) - def to_mongo(self, value, **kwargs): + def to_mongo(self, value): return value def to_python(self, value):