def test_foreignkey_filters_produced(self): """ A ForeignKey should produce a list of the possible related objects, with counts. """ # Make another Genre that isn't used new_g, created = Genre.objects.get_or_create(name='Nonsense') assert created data = MultiValueDict() filter_ = ForeignKeyFilter('genre', Book, data) qs = Book.objects.all() choices = [(c.label, c.count) for c in filter_.get_choices(qs)] reached = [False, False] for g in Genre.objects.all(): count = g.book_set.count() if count == 0: reached[0] = True self.assertTrue((g.name, count) not in choices) else: reached[1] = True self.assertTrue((g.name, count) in choices) self.assertTrue(reached[0]) self.assertTrue(reached[1])
def test_foreignkey_invalid_query(self): self.do_invalid_query_param_test( lambda params: ForeignKeyFilter('genre', Book, params), MultiValueDict({'genre': ['xxx']})) self.do_missing_related_object_test( lambda params: ForeignKeyFilter('genre', Book, params), MultiValueDict({'genre': ['1000']}))
def test_normalize_choices(self): # We shouldn't get links for non-nullable fields when there is only one choice. # Make sure there are no other books in 1975 clark = Author.objects.get(name='Arthur C. Clarke') qs = Book.objects.filter(date_published__year=1861) self.assertEqual(len(qs), 1) filter1 = ChoicesFilter('binding', Book, MultiValueDict()) choices1 = filter1.get_choices(qs) self.assertEqual(len(choices1), 1) self.assertEqual(choices1[0].link_type, FILTER_DISPLAY, choices1) filter2 = ForeignKeyFilter('genre', Book, MultiValueDict()) choices2 = filter2.get_choices(qs) self.assertEqual(len(choices2), 1) self.assertEqual(choices2[0].link_type, FILTER_DISPLAY, choices2)
def test_order_by_count(self): """ Tests the 'order_by_count' option. """ filter1 = ForeignKeyFilter('genre', Book, MultiValueDict(), order_by_count=True) qs = Book.objects.all() choices1 = filter1.get_choices(qs) # Should be same after sorting by 'count' self.assertEqual(choices1, sorted(choices1, key=operator.attrgetter('count'), reverse=True)) filter2 = ForeignKeyFilter('genre', Book, MultiValueDict(), order_by_count=False) choices2 = filter2.get_choices(qs) # Should be same after sorting by 'label' (that is equal to Genre.name, # and Genre ordering is by that field) self.assertEqual(choices2, sorted(choices2, key=operator.attrgetter('label')))
def test_order_by_count(self): """ Tests the 'order_by_count' option. """ filter1 = ForeignKeyFilter('genre', Book, MultiValueDict(), order_by_count=True) qs = Book.objects.all() choices1 = filter1.get_choices(qs) # Should be same after sorting by 'count' self.assertEqual( choices1, sorted(choices1, key=operator.attrgetter('count'), reverse=True)) filter2 = ForeignKeyFilter('genre', Book, MultiValueDict(), order_by_count=False) choices2 = filter2.get_choices(qs) # Should be same after sorting by 'label' (that is equal to Genre.name, # and Genre ordering is by that field) self.assertEqual(choices2, sorted(choices2, key=operator.attrgetter('label')))
def test_foreignkey_params_produced(self): """ A ForeignKey filter shoud produce params that cause the query to be limited by that filter. """ qs = Book.objects.all() data = MultiValueDict() filter1 = ForeignKeyFilter('genre', Book, data) choices = filter1.get_choices(qs) # If we use the params from e.g. the first choice, that should produce a # filtered qs when fed back in (i.e. when we 'click' on that option we # should get a filter on it). reached = False for choice in choices: reached = True filter2 = ForeignKeyFilter('genre', Book, choice.params) qs_filtered = filter2.apply_filter(qs) self.assertEqual(len(qs_filtered), choice.count) for book in qs_filtered: self.assertEqual(unicode(book.genre), choice.label) self.assertTrue(reached)
def test_foreignkey_remove_link(self): """ Ensure that a ForeignKey Filter will turn into a 'remove' link when an item has been selected. """ qs = Book.objects.all() data = MultiValueDict() filter1 = ForeignKeyFilter('genre', Book, data) choices = filter1.get_choices(qs) choice = choices[0] filter2 = ForeignKeyFilter('genre', Book, choice.params) qs_filtered = filter2.apply_filter(qs) choices2 = filter2.get_choices(qs_filtered) # Should have one item self.assertEqual(1, len(choices2)) self.assertEqual(choices2[0].link_type, FILTER_REMOVE) self.assertEqual(choices2[0].label, choice.label) # 'Clicking' should remove filtering filter3 = ForeignKeyFilter('genre', Book, choices2[0].params) qs_reverted = filter3.apply_filter(qs) self.assertEqual(qs, qs_reverted)
def test_foreignkey_params_produced(self): """ A ForeignKey filter shoud produce params that cause the query to be limited by that filter. """ qs = Book.objects.all() data = MultiValueDict() filter1 = ForeignKeyFilter('genre', Book, data) choices = filter1.get_choices(qs) # If we use the params from e.g. the first choice, that should produce a # filtered qs when fed back in (i.e. when we 'click' on that option we # should get a filter on it). reached = False for choice in choices: reached = True filter2 = ForeignKeyFilter('genre', Book, choice.params) qs_filtered = filter2.apply_filter(qs) self.assertEqual(len(qs_filtered), choice.count) for book in qs_filtered: self.assertEqual(text_type(book.genre), choice.label) self.assertTrue(reached)