def previous_page_info(self) -> Optional[dict]: """Returns a dictionary which can be given to FlowPaginator.page() to get the previous page. @see info() Internal information ; notice that 'type' will always be 'backward'. """ if self.has_previous(): populate_related(self.object_list, (self._attr_name, )) object_iter = iter(self.object_list) value = self._key_field_info.value_from(next(object_iter)) offset = self._compute_offset(value, object_iter) if offset == self._max_size - 1: # NB: _max_size > 1 # The duplicates fill this page & there can be some duplicates on the next page(s) if self._forward: # NB: it's easy to see (with a sketch) that # duplicates_count = forward_offset + backward_offset + 1 # (with here forward_offset == self._offset & backward_offset == offset) offset = self._get_duplicates_count( value) - self._offset - 1 elif self._offset: # Offsets are in the same direction (backward) => we cumulate them offset += self._offset + 1 return self._build_info(_BACKWARD, value, offset) return None
def test_populate_related05(self): "Two fields related to the same model" user = self.login() create_contact = partial(FakeContact.objects.create, user=user, last_name='Simpson') marge = create_contact(first_name='Marge') homer = create_contact(first_name='Homer') rel = Relation.objects.create( user=user, type_id=REL_SUB_HAS, subject_entity=marge, object_entity=homer, ) rel = self.refresh(rel) # NB: we fill the ContentType cache to not disturb assertNumQueries() ContentType.objects.get_for_model(CremeEntity) with self.assertNumQueries(1): populate_related([rel], ['subject_entity', 'object_entity']) with self.assertNumQueries(0): e1 = rel.subject_entity self.assertEqual(marge, e1.get_real_entity())
def next_page_info(self) -> Optional[dict]: """Returns a dictionary which can be given to FlowPaginator.page() to get the next page. @see info() Internal information ; notice that 'type' will always be 'forward'. """ next_item = self._next_item if next_item is not None: populate_related([next_item, *self.object_list], (self._attr_name, )) value = self._key_field_info.value_from(next_item) offset = self._compute_offset(value, reversed(self.object_list)) if offset == self._max_size: # The duplicates fill this page & there can be some duplicates # on the previous page(s) if self._forward: # Offsets are in the same direction (forward) => we accumulate them offset += self._offset else: # NB: it's easy to see (with a sketch) that # duplicates_count = forward_offset + backward_offset + 1 # (with here forward_offset == offset & backward_offset == self._offset) offset = self._get_duplicates_count( value) - self._offset - 1 return self._build_info(_FORWARD, value, offset) return None
def test_populate_related04(self): "Partially cached" self.login() contacts = self._create_contacts() __ = contacts[0].sector # __ = contacts[1].sector # Not Cached with self.assertNumQueries(2): populate_related(contacts, ['sector', 'civility'])
def test_populate_related03(self): "Do not retrieve already cached values" self.login() contacts = self._create_contacts() __ = contacts[0].sector __ = contacts[1].sector with self.assertNumQueries(1): populate_related(contacts, ['sector', 'civility'])
def test_populate_related08(self): "Two fields + depth > 1 => instances of level 2 have different models" user = self.login() user2 = self.other_user create_folder = partial(FakeFolder.objects.create, user=user) folder1 = create_folder(title='Maps') folder11 = create_folder(title='Earth maps', parent=folder1) folder2 = create_folder(title='Blue prints') create_doc = partial(FakeDocument.objects.create, user=user) docs = [ create_doc(title='Japan map part#1', linked_folder=folder1), create_doc(title='Mars city 1', linked_folder=folder11), create_doc(title='Swordfish', linked_folder=folder2, user=user2), ] docs = [self.refresh(c) for c in docs] # 3 queries: # 1 for fhe folders of the first level. # 0 for fhe folders of the second level, because already in the cache. # 1 for the users. # 1 for the roles. with self.assertNumQueries(3): populate_related(docs, ['linked_folder__parent', 'user__role']) # Folders with self.assertNumQueries(0): f1 = docs[0].linked_folder self.assertEqual(folder1, f1) with self.assertNumQueries(0): f11 = docs[1].linked_folder self.assertEqual(folder11, f11) with self.assertNumQueries(0): f1 = f11.parent self.assertEqual(folder1, f1) with self.assertNumQueries(0): f2 = docs[2].linked_folder self.assertEqual(folder2, f2) # Users with self.assertNumQueries(0): u1 = docs[0].user self.assertEqual(user, u1) with self.assertNumQueries(0): u2 = docs[2].user self.assertEqual(user2, u2) with self.assertNumQueries(0): role = u2.role self.assertEqual(self.role, role)
def test_populate_related06(self): "depth = 1" self.login() contacts = self._create_contacts() with self.assertNumQueries(1): populate_related(contacts, ['sector__title']) with self.assertNumQueries(0): s1 = contacts[0].sector self.assertEqual(self.sector1, s1)
def test_populate_related09(self): "Already cached field (level 2)" user = self.login() user2 = self.other_user create_contact = partial(FakeContact.objects.create, user=user, last_name='Simpson') contacts = [ create_contact(first_name='Homer'), create_contact(first_name='Lisa', user=user2), ] contacts = [self.refresh(c) for c in contacts] _ = contacts[1].user # 'user' is cached with self.assertNumQueries(2): populate_related(contacts, ['user__role__name'])
def test_populate_related02(self): "Two fields" self.login() contacts = self._create_contacts() with self.assertNumQueries(2): populate_related(contacts, ['sector', 'civility', 'last_name']) with self.assertNumQueries(0): s1 = contacts[0].sector self.assertEqual(self.sector1, s1) with self.assertNumQueries(0): c1 = contacts[1].civility self.assertEqual(self.civ1, c1) self.assertIsNone(contacts[2].civility)
def get_template_context(self, context, **kwargs): person = context['object'] model = type(person) is_hidden = context['fields_configs'].get_4_model( model).is_field_hidden def prepare_address(attr_name): display_button = display_content = False try: addr = getattr(person, attr_name) except AttributeError: addr = Address() else: if is_hidden(model._meta.get_field(attr_name)): if addr is None: addr = Address() elif addr is None: addr = Address() display_button = True else: display_content = True addr.display_button = display_button addr.display_content = display_content addr.owner = person # NB: avoids a query (per address) for credentials. return addr populate_related((person, ), ['billing_address', 'shipping_address']) b_address = prepare_address('billing_address') s_address = prepare_address('shipping_address') build_cell = partial(EntityCellRegularField.build, model=Address) return super().get_template_context( context, b_address=b_address, s_address=s_address, cells=OrderedDict((fname, build_cell(name=fname)) for fname in _get_address_field_names()), )
def test_populate_related01(self): "One field" self.login() with self.assertNoException(): populate_related([], ['sector']) contacts = self._create_contacts() with self.assertNumQueries(1): populate_related(contacts, ['sector']) with self.assertNumQueries(0): s1 = contacts[0].sector self.assertEqual(self.sector1, s1) with self.assertNumQueries(0): s2 = contacts[1].sector self.assertEqual(self.sector2, s2) self.assertIsNone(contacts[2].sector)
def test_populate_related07(self): "Field with depth=1 is a FK" user = self.login() create_folder = partial(FakeFolder.objects.create, user=user) folder1 = create_folder(title='Maps') folder11 = create_folder(title='Earth maps', parent=folder1) folder12 = create_folder(title='Mars maps', parent=folder1) folder2 = create_folder(title='Blue prints') create_doc = partial(FakeDocument.objects.create, user=user) docs = [ create_doc(title='Japan map part#1', linked_folder=folder11), create_doc(title='Japan map part#2', linked_folder=folder11), create_doc(title='Mars city 1', linked_folder=folder12), create_doc(title='Swordfish', linked_folder=folder2), ] docs = [self.refresh(c) for c in docs] with self.assertNumQueries(2): populate_related(docs, ['linked_folder__parent', 'title']) with self.assertNumQueries(0): f11 = docs[0].linked_folder self.assertEqual(folder11, f11) with self.assertNumQueries(0): f1 = f11.parent self.assertEqual(folder1, f1) with self.assertNumQueries(0): f2 = docs[3].linked_folder self.assertEqual(folder2, f2) with self.assertNumQueries(0): f_null = f2.parent self.assertIsNone(f_null)