Updated field filter logic - can now exclude subclass fields (#443)

This commit is contained in:
Ross Lawley 2013-08-20 12:21:20 +00:00
parent 661398d891
commit 29c887f30b
3 changed files with 50 additions and 5 deletions

View File

@ -4,6 +4,7 @@ Changelog
Changes in 0.8.4 Changes in 0.8.4
================ ================
- Fixed can now exclude subclass fields (#443)
- Fixed dereference issue with embedded listfield referencefields (#439) - Fixed dereference issue with embedded listfield referencefields (#439)
- Fixed slice when using inheritance causing fields to be excluded (#437) - Fixed slice when using inheritance causing fields to be excluded (#437)
- Fixed ._get_db() attribute after a Document.switch_db() (#441) - Fixed ._get_db() attribute after a Document.switch_db() (#441)

View File

@ -14,8 +14,9 @@ from pymongo.common import validate_read_preference
from mongoengine import signals from mongoengine import signals
from mongoengine.common import _import_class from mongoengine.common import _import_class
from mongoengine.base.common import get_document
from mongoengine.errors import (OperationError, NotUniqueError, from mongoengine.errors import (OperationError, NotUniqueError,
InvalidQueryError) InvalidQueryError, LookUpError)
from mongoengine.queryset import transform from mongoengine.queryset import transform
from mongoengine.queryset.field_list import QueryFieldList from mongoengine.queryset.field_list import QueryFieldList
@ -1333,13 +1334,33 @@ class BaseQuerySet(object):
return frequencies return frequencies
def _fields_to_dbfields(self, fields): def _fields_to_dbfields(self, fields, subdoc=False):
"""Translate fields paths to its db equivalents""" """Translate fields paths to its db equivalents"""
ret = [] ret = []
subclasses = []
document = self._document
if document._meta['allow_inheritance']:
subclasses = [get_document(x)
for x in document._subclasses][1:]
for field in fields: for field in fields:
field = ".".join(f.db_field for f in try:
self._document._lookup_field(field.split('.'))) field = ".".join(f.db_field for f in
ret.append(field) document._lookup_field(field.split('.')))
ret.append(field)
except LookUpError, e:
found = False
for subdoc in subclasses:
try:
subfield = ".".join(f.db_field for f in
subdoc._lookup_field(field.split('.')))
ret.append(subfield)
found = True
break
except LookUpError, e:
pass
if not found:
raise e
return ret return ret
def _get_order_by(self, keys): def _get_order_by(self, keys):

View File

@ -399,5 +399,28 @@ class OnlyExcludeAllTest(unittest.TestCase):
numbers = Numbers.objects.fields(embedded__n={"$slice": [-5, 10]}).get() numbers = Numbers.objects.fields(embedded__n={"$slice": [-5, 10]}).get()
self.assertEqual(numbers.embedded.n, [-5, -4, -3, -2, -1]) self.assertEqual(numbers.embedded.n, [-5, -4, -3, -2, -1])
def test_exclude_from_subclasses_docs(self):
class Base(Document):
username = StringField()
meta = {'allow_inheritance': True}
class Anon(Base):
anon = BooleanField()
class User(Base):
password = StringField()
wibble = StringField()
Base.drop_collection()
User(username="mongodb", password="secret").save()
user = Base.objects().exclude("password", "wibble").first()
self.assertEqual(user.password, None)
self.assertRaises(LookUpError, Base.objects.exclude, "made_up")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()