def test_get_specs_using_default_filter(self): class BarFilterSet(FilterSet): id = Filter(form_field=forms.IntegerField(), is_default=True) other = Filter( source="stuff", form_field=forms.CharField(), default_lookup="contains" ) thing = Filter(form_field=forms.IntegerField(min_value=0, max_value=15)) class FooFilterSet(FilterSet): field = Filter(form_field=forms.CharField(), is_default=True) bar = BarFilterSet() def _test(data, expected, **kwargs): fs = FooFilterSet(data=QueryDict(data), queryset=[], **kwargs) assert set(fs.get_specs()) == set(expected) _test("bar=5", [FilterSpec(["bar", "id"], "exact", 5, False)]) _test("bar__isnull=True", [FilterSpec(["bar", "id"], "isnull", True, False)]) _test("bar__gt=foo", [], strict_mode=StrictMode.drop) _test("page=1", [], strict_mode=StrictMode.fail) with pytest.raises(forms.ValidationError): _test("bar=aa", [], strict_mode=StrictMode.fail) with pytest.raises(Empty): _test("bar__in=aa", [], strict_mode=StrictMode.empty)
def test_get_specs_using_default_filter(self): class BarFilterSet(FilterSet): id = Filter(form_field=forms.IntegerField(), is_default=True) other = Filter(source='stuff', form_field=forms.CharField(), default_lookup='contains') thing = Filter( form_field=forms.IntegerField(min_value=0, max_value=15)) class FooFilterSet(FilterSet): field = Filter(form_field=forms.CharField(), is_default=True) bar = BarFilterSet() def _test(data, expected, **kwargs): fs = FooFilterSet(data=QueryDict(data), queryset=[], **kwargs) assert set(fs.get_specs()) == set(expected) _test('bar=5', [ FilterSpec(['bar', 'id'], 'exact', 5, False), ]) _test('bar__isnull=True', [ FilterSpec(['bar', 'id'], 'isnull', True, False), ]) _test('bar__gt=foo', []) _test('page=1', [], strict_mode=StrictMode.fail)
def test_get_spec(self): p = Filter(source='parent', form_field=forms.CharField()) f = Filter(source='child', form_field=forms.CharField()) f.parent = p assert f.get_spec(LookupConfig('key', 'value')) == FilterSpec(['child'], 'exact', 'value', False) assert f.get_spec(LookupConfig('key!', 'value')) == FilterSpec(['child'], 'exact', 'value', True) assert f.get_spec(LookupConfig( 'key', {'contains': 'value'})) == FilterSpec(['child'], 'contains', 'value', False) with pytest.raises(forms.ValidationError): assert f.get_spec(LookupConfig('key', {'foo': 'value'})) with pytest.raises(forms.ValidationError): assert f.get_spec( LookupConfig('key', { 'foo': 'value', 'happy': 'rainbows', }))
def test_repr(self): assert repr(FilterSpec(['a', 'b'], 'exact', 'value', False)) == ('<FilterSpec a.b exact {}>'.format( repr('value'))) assert repr(FilterSpec( ['a', 'b'], 'exact', 'value', True)) == ('<FilterSpec a.b NOT exact {}>'.format(repr('value')))
def test_filter_isnull(self): self._test_filter( FilterSpec(['nulldata'], 'isnull', True, False), [DATA[1]] ) self._test_filter( FilterSpec(['nulldata'], 'isnull', False, False), [DATA[0]] )
def test_equality(self): a = FilterSpec(['a', 'b'], 'exact', 'value', False) b = FilterSpec(['a', 'b'], 'exact', 'value', False) c = FilterSpec(['a', 'b'], 'exact', 'value', True) d = FilterSpec(['a', 'b'], 'contains', 'value', False) assert a == b assert a != c assert a != d
def test_equality(self): a = FilterSpec(["a", "b"], "exact", "value", False) b = FilterSpec(["a", "b"], "exact", "value", False) c = FilterSpec(["a", "b"], "exact", "value", True) d = FilterSpec(["a", "b"], "contains", "value", False) assert a == b assert a != c assert a != d
def test_excludes(self): backend = DjangoFilterBackend(Place.objects.all()) backend.bind([ FilterSpec(["name"], "exact", "value", False), FilterSpec(["address"], "contains", "value", True), ]) assert list(backend.excludes) == [ FilterSpec(["address"], "contains", "value", True) ]
def test_excludes(self): backend = DjangoFilterBackend(Place.objects.all()) backend.bind([ FilterSpec(['name'], 'exact', 'value', False), FilterSpec(['address'], 'contains', 'value', True), ]) assert list(backend.excludes) == [ FilterSpec(['address'], 'contains', 'value', True), ]
def test_filter(self): qs = mock.Mock() backend = DjangoFilterBackend(qs) backend.bind([ FilterSpec(['name'], 'exact', 'value', False), FilterSpec(['address'], 'contains', 'value', True), ]) result = backend.filter() assert result == qs.filter.return_value.exclude.return_value qs.filter.assert_called_once_with(name__exact='value') qs.filter.return_value.exclude.assert_called_once_with(address__contains='value')
def test_filter(self): qs = mock.Mock() backend = DjangoFilterBackend(qs) backend.model = Place backend.bind([ FilterSpec(["name"], "exact", "value", False), FilterSpec(["address"], "contains", "value", True), ]) result = backend.filter() assert result == qs.filter.return_value.exclude.return_value qs.filter.assert_called_once_with(name__exact="value") qs.filter.return_value.exclude.assert_called_once_with( address__contains="value")
def test_repr(self): assert repr(FilterSpec(['a', 'b'], 'exact', 'value', False)) == ( '<FilterSpec a.b exact {}>'.format(repr('value')) ) assert repr(FilterSpec(['a', 'b'], 'exact', 'value', True)) == ( '<FilterSpec a.b NOT exact {}>'.format(repr('value')) ) class Foo(object): def foo(self): pass f = Foo() assert repr(FilterSpec(['a', 'b'], 'exact', 'value', False, filter_callable=f.foo)) == ( '<FilterSpec a.b exact {} via Foo.foo>'.format(repr('value')) )
def test_get_spec(self): class Foo(CallableFilter): @form_field_for_filter(forms.CharField()) def filter_foo_for_django(self): pass p = Filter(source='parent', form_field=forms.CharField()) p.filter_backend = DjangoFilterBackend(queryset=[]) f = Foo(source='child', default_lookup='foo') f.parent = p assert f.get_spec(LookupConfig('key', 'value')) == FilterSpec( ['child'], 'foo', 'value', False, f.filter_foo_for_django)
def test_repr(self): assert repr(FilterSpec(["a", "b"], "exact", "value", False)) == ("<FilterSpec a.b exact {}>".format( repr("value"))) assert repr(FilterSpec( ["a", "b"], "exact", "value", True)) == ("<FilterSpec a.b NOT exact {}>".format(repr("value"))) class Foo(object): def foo(self): pass f = Foo() assert repr( FilterSpec(["a", "b"], "exact", "value", False, filter_callable=f.foo)) == ( "<FilterSpec a.b exact {} via Foo.foo>".format( repr("value")))
def test_get_spec(self): class Foo(CallableFilter): @form_field_for_filter(forms.CharField()) def filter_foo_for_django(self): pass p = Filter(source="parent", form_field=forms.CharField()) p.filter_backend = DjangoFilterBackend(queryset=[]) f = Foo(source="child", default_lookup="foo") f.parent = p assert f.get_spec(LookupConfig("key", "value")) == FilterSpec( ["child"], "foo", "value", False, f.filter_foo_for_django )
def test_filter_callable_specs(self): qs = mock.Mock() def foo(queryset, spec): return queryset.filter(spec) spec = FilterSpec(["name"], "exact", "value", False, foo) backend = DjangoFilterBackend(qs) backend.bind([spec]) result = backend.filter() assert result == qs.filter.return_value qs.filter.assert_called_once_with(spec)
def test_filter_to_many(self): qs = mock.Mock() backend = DjangoFilterBackend(qs) backend.model = Place backend.bind([ FilterSpec(["restaurant", "waiter", "name"], "exact", "value", False) ]) result = backend.filter() assert result == qs.filter.return_value.distinct.return_value qs.filter.assert_called_once_with( restaurant__waiter__name__exact="value")
def test_filter_to_many(self): qs = mock.Mock() backend = DjangoFilterBackend(qs) backend.model = Place backend.bind([ FilterSpec(['restaurant', 'waiter', 'name'], 'exact', 'value', False), ]) result = backend.filter() assert result == qs.filter.return_value.distinct.return_value qs.filter.assert_called_once_with( restaurant__waiter__name__exact='value')
def test_get_spec(self): p = Filter(source="parent", form_field=forms.CharField()) f = Filter(source="child", form_field=forms.CharField()) f.parent = p assert f.get_spec(LookupConfig("key", "value")) == FilterSpec( ["child"], "exact", "value", False ) assert f.get_spec(LookupConfig("key!", "value")) == FilterSpec( ["child"], "exact", "value", True ) assert f.get_spec(LookupConfig("key", {"contains": "value"})) == FilterSpec( ["child"], "contains", "value", False ) with pytest.raises(forms.ValidationError): assert f.get_spec(LookupConfig("key", {"foo": "value"})) with pytest.raises(forms.ValidationError): assert f.get_spec( LookupConfig("key", {"foo": "value", "happy": "rainbows"}) ) with pytest.raises(forms.ValidationError): f.no_lookup = True assert f.get_spec(LookupConfig("key", {"exact": "value"}))
def test_filter_already_eagerloaded(self, alchemy_db): backend = SQLAlchemyFilterBackend( alchemy_db.query(Place).options( joinedload(Place.restaurant).joinedload( Restaurant.waiter_set)), ) backend.bind([ FilterSpec(['restaurant', 'waiter_set', 'name'], 'exact', 'John', False), ]) filtered = backend.filter() sql = six.text_type(filtered) assert 'place JOIN one_to_one' not in sql assert 'place LEFT OUTER JOIN one_to_one' in sql
def _test_build_clause(self, alchemy_db, name, lookup, value, expected, is_negated=False): backend = SQLAlchemyFilterBackend(alchemy_db.query(Place), ) clause, to_join = backend.build_clause( FilterSpec(['restaurant', 'waiter_set', name], lookup, value, is_negated)) assert to_join == [Place.restaurant, Restaurant.waiter_set] assert_alchemy_expressions_equal(clause, expected)
def test_filter(self, alchemy_db): backend = SQLAlchemyFilterBackend(alchemy_db.query(Place)) backend.bind([ FilterSpec(["restaurant", "waiter_set", "name"], "exact", "John", False) ]) filtered = backend.filter() sql = six.text_type(filtered) # eagerloads via outerjoin assert "LEFT OUTER JOIN one_to_one_restaurant" not in sql assert "LEFT OUTER JOIN one_to_one_waiter" not in sql # for filtering via inner join assert "JOIN one_to_one_restaurant" in sql assert "JOIN one_to_one_waiter" in sql
def test_filter(self, alchemy_db): backend = SQLAlchemyFilterBackend(alchemy_db.query(Place), ) backend.bind([ FilterSpec(['restaurant', 'waiter_set', 'name'], 'exact', 'John', False), ]) filtered = backend.filter() assert six.text_type(filtered) == ( 'SELECT one_to_one_place.id AS one_to_one_place_id, ' 'one_to_one_place.name AS one_to_one_place_name, ' 'one_to_one_place.address AS one_to_one_place_address \n' 'FROM one_to_one_place ' 'JOIN one_to_one_restaurant ' 'ON one_to_one_restaurant.place_id = one_to_one_place.id ' 'JOIN one_to_one_waiter ' 'ON one_to_one_waiter.restaurant_id = one_to_one_restaurant.place_id ' '\nWHERE one_to_one_waiter.name = :name_1')
def test_filter_exception_handling(self): self._test_filter(FilterSpec(["id"], "week_day", 1, False), DATA)
def test_filter_contains(self): self._test_filter( FilterSpec(["restaurant", "waiters", "name"], "contains", "Jo", False), [DATA[0]], )
def test_prepare_spec(self): backend = DjangoFilterBackend(Place.objects.all()) spec = backend._prepare_spec(FilterSpec(["name"], "exact", "value")) assert spec == "name__exact"
def test_filter_endswith(self): self._test_filter( FilterSpec(["restaurant", "waiters", "name"], "endswith", "e", False), DATA)
def test_prepare_spec(self): backend = DjangoFilterBackend(Place.objects.all()) spec = backend._prepare_spec(FilterSpec(['name'], 'exact', 'value')) assert spec == 'name__exact'
def test_filter_exact(self): self._test_filter( FilterSpec(["restaurant", "waiters", "name"], "exact", "John", False), [])
def test_get_specs(self): class BarFilterSet(FilterSet): other = Filter(source='stuff', form_field=forms.CharField(), default_lookup='contains') thing = Filter( form_field=forms.IntegerField(min_value=0, max_value=15)) class FooFilterSet(FilterSet): field = Filter(form_field=forms.CharField()) bar = BarFilterSet() def _test(data, expected, **kwargs): fs = FooFilterSet(data=QueryDict(data), queryset=[], **kwargs) assert set(fs.get_specs()) == set(expected) _test('field=earth&bar__other=mars', [ FilterSpec(['field'], 'exact', 'earth', False), FilterSpec(['bar', 'stuff'], 'contains', 'mars', False), ]) _test('field!=earth&bar__other=mars', [ FilterSpec(['field'], 'exact', 'earth', True), FilterSpec(['bar', 'stuff'], 'contains', 'mars', False), ]) _test('field__in=earth,pluto&bar__other__icontains!=mars', [ FilterSpec(['field'], 'in', ['earth', 'pluto'], False), FilterSpec(['bar', 'stuff'], 'icontains', 'mars', True), ]) _test('fields__in=earth,pluto&bar__other__icontains!=mars', [ FilterSpec(['bar', 'stuff'], 'icontains', 'mars', True), ]) _test('field__in=earth,pluto&bar__ot!her__icontains!=mars', [ FilterSpec(['field'], 'in', ['earth', 'pluto'], False), ]) _test('bar__thing=5', [ FilterSpec(['bar', 'thing'], 'exact', 5, False), ]) _test('bar__thing__in=5,10,15', [ FilterSpec(['bar', 'thing'], 'in', [5, 10, 15], False), ]) _test('bar__thing__range=5,10', [ FilterSpec(['bar', 'thing'], 'range', [5, 10], False), ]) _test('bar=5', []) _test('bar__thing__range=5,10,15', []) _test('bar__thing=100', []) _test('bar__thing__in=100,5', []) with pytest.raises(forms.ValidationError): _test('bar__thing__in=100,5', [], strict_mode=StrictMode.fail)