Dereferencing of referenced documents within lists

This commit is contained in:
Harry Marr 2010-02-12 02:31:41 +00:00
parent b2588d1c4f
commit 210e9e23af
2 changed files with 51 additions and 0 deletions

View File

@ -155,6 +155,29 @@ class ListField(BaseField):
self.field = field self.field = field
super(ListField, self).__init__(**kwargs) super(ListField, self).__init__(**kwargs)
def __get__(self, instance, owner):
"""Descriptor to automatically dereference references.
"""
if instance is None:
# Document class being used rather than a document object
return self
if isinstance(self.field, ReferenceField):
referenced_type = self.field.document_type
# Get value from document instance if available
value_list = instance._data.get(self.name)
deref_list = []
for value in value_list:
# Dereference DBRefs
if isinstance(value, (pymongo.dbref.DBRef)):
value = _get_db().dereference(value)
deref_list.append(referenced_type._from_son(value))
else:
deref_list.append(value)
instance._data[self.name] = deref_list
return super(ListField, self).__get__(instance, owner)
def to_python(self, value): def to_python(self, value):
return [self.field.to_python(item) for item in value] return [self.field.to_python(item) for item in value]

View File

@ -286,6 +286,34 @@ class FieldTest(unittest.TestCase):
User.drop_collection() User.drop_collection()
BlogPost.drop_collection() BlogPost.drop_collection()
def test_list_item_dereference(self):
"""Ensure that DBRef items in ListFields are dereferenced.
"""
class User(Document):
name = StringField()
class Group(Document):
members = ListField(ReferenceField(User))
User.drop_collection()
Group.drop_collection()
user1 = User(name='user1')
user1.save()
user2 = User(name='user2')
user2.save()
group = Group(members=[user1, user2])
group.save()
group_obj = Group.objects.first()
self.assertEqual(group_obj.members[0].name, user1.name)
self.assertEqual(group_obj.members[1].name, user2.name)
User.drop_collection()
Group.drop_collection()
def test_reference_query_conversion(self): def test_reference_query_conversion(self):
"""Ensure that ReferenceFields can be queried using objects and values """Ensure that ReferenceFields can be queried using objects and values
of the type of the primary key of the referenced object. of the type of the primary key of the referenced object.