Do not keep calling _dereference on values if it has already been dereferenced.
This commit is contained in:
		| @@ -105,6 +105,14 @@ class FieldTest(unittest.TestCase): | ||||
|  | ||||
|             [m for m in group_obj.members] | ||||
|             self.assertEqual(q, 2) | ||||
|             self.assertTrue(group_obj._data['members']._dereferenced) | ||||
|  | ||||
|             # verifies that no additional queries gets executed | ||||
|             # if we re-iterate over the ListField once it is | ||||
|             # dereferenced | ||||
|             [m for m in group_obj.members] | ||||
|             self.assertEqual(q, 2) | ||||
|             self.assertTrue(group_obj._data['members']._dereferenced) | ||||
|  | ||||
|         # Document select_related | ||||
|         with query_counter() as q: | ||||
| @@ -125,6 +133,46 @@ class FieldTest(unittest.TestCase): | ||||
|                 [m for m in group_obj.members] | ||||
|                 self.assertEqual(q, 2) | ||||
|  | ||||
|     def test_list_item_dereference_orphan_dbref(self): | ||||
|         """Ensure that orphan DBRef items in ListFields are dereferenced. | ||||
|         """ | ||||
|         class User(Document): | ||||
|             name = StringField() | ||||
|  | ||||
|         class Group(Document): | ||||
|             members = ListField(ReferenceField(User, dbref=False)) | ||||
|  | ||||
|         User.drop_collection() | ||||
|         Group.drop_collection() | ||||
|  | ||||
|         for i in range(1, 51): | ||||
|             user = User(name='user %s' % i) | ||||
|             user.save() | ||||
|  | ||||
|         group = Group(members=User.objects) | ||||
|         group.save() | ||||
|         group.reload()  # Confirm reload works | ||||
|  | ||||
|         # Delete one User so one of the references in the | ||||
|         # Group.members list is an orphan DBRef | ||||
|         User.objects[0].delete() | ||||
|         with query_counter() as q: | ||||
|             self.assertEqual(q, 0) | ||||
|  | ||||
|             group_obj = Group.objects.first() | ||||
|             self.assertEqual(q, 1) | ||||
|  | ||||
|             [m for m in group_obj.members] | ||||
|             self.assertEqual(q, 2) | ||||
|             self.assertTrue(group_obj._data['members']._dereferenced) | ||||
|  | ||||
|             # verifies that no additional queries gets executed | ||||
|             # if we re-iterate over the ListField once it is | ||||
|             # dereferenced | ||||
|             [m for m in group_obj.members] | ||||
|             self.assertEqual(q, 2) | ||||
|             self.assertTrue(group_obj._data['members']._dereferenced) | ||||
|  | ||||
|         User.drop_collection() | ||||
|         Group.drop_collection() | ||||
|  | ||||
| @@ -505,6 +553,61 @@ class FieldTest(unittest.TestCase): | ||||
|                 for m in group_obj.members: | ||||
|                     self.assertIn('User', m.__class__.__name__) | ||||
|  | ||||
|  | ||||
|     def test_generic_reference_orphan_dbref(self): | ||||
|         """Ensure that generic orphan DBRef items in ListFields are dereferenced. | ||||
|         """ | ||||
|  | ||||
|         class UserA(Document): | ||||
|             name = StringField() | ||||
|  | ||||
|         class UserB(Document): | ||||
|             name = StringField() | ||||
|  | ||||
|         class UserC(Document): | ||||
|             name = StringField() | ||||
|  | ||||
|         class Group(Document): | ||||
|             members = ListField(GenericReferenceField()) | ||||
|  | ||||
|         UserA.drop_collection() | ||||
|         UserB.drop_collection() | ||||
|         UserC.drop_collection() | ||||
|         Group.drop_collection() | ||||
|  | ||||
|         members = [] | ||||
|         for i in range(1, 51): | ||||
|             a = UserA(name='User A %s' % i) | ||||
|             a.save() | ||||
|  | ||||
|             b = UserB(name='User B %s' % i) | ||||
|             b.save() | ||||
|  | ||||
|             c = UserC(name='User C %s' % i) | ||||
|             c.save() | ||||
|  | ||||
|             members += [a, b, c] | ||||
|  | ||||
|         group = Group(members=members) | ||||
|         group.save() | ||||
|  | ||||
|         # Delete one UserA instance so that there is | ||||
|         # an orphan DBRef in the GenericReference ListField | ||||
|         UserA.objects[0].delete() | ||||
|         with query_counter() as q: | ||||
|             self.assertEqual(q, 0) | ||||
|  | ||||
|             group_obj = Group.objects.first() | ||||
|             self.assertEqual(q, 1) | ||||
|  | ||||
|             [m for m in group_obj.members] | ||||
|             self.assertEqual(q, 4) | ||||
|             self.assertTrue(group_obj._data['members']._dereferenced) | ||||
|  | ||||
|             [m for m in group_obj.members] | ||||
|             self.assertEqual(q, 4) | ||||
|             self.assertTrue(group_obj._data['members']._dereferenced) | ||||
|  | ||||
|         UserA.drop_collection() | ||||
|         UserB.drop_collection() | ||||
|         UserC.drop_collection() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user