Skip to content

Commit 8c48516

Browse files
authored
Also convert BaseCSVFilter for custom fields (#1081)
1 parent 2d0b9dd commit 8c48516

File tree

3 files changed

+60
-10
lines changed

3 files changed

+60
-10
lines changed

graphene_django/filter/tests/test_in_filter.py

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import pytest
22

3+
from django_filters import FilterSet
4+
from django_filters import rest_framework as filters
35
from graphene import ObjectType, Schema
46
from graphene.relay import Node
57
from graphene_django import DjangoObjectType
6-
from graphene_django.tests.models import Pet
8+
from graphene_django.tests.models import Pet, Person
79
from graphene_django.utils import DJANGO_FILTER_INSTALLED
810

911
pytestmark = []
@@ -28,8 +30,27 @@ class Meta:
2830
}
2931

3032

33+
class PersonFilterSet(FilterSet):
34+
class Meta:
35+
model = Person
36+
fields = {}
37+
38+
names = filters.BaseInFilter(method="filter_names")
39+
40+
def filter_names(self, qs, name, value):
41+
return qs.filter(name__in=value)
42+
43+
44+
class PersonNode(DjangoObjectType):
45+
class Meta:
46+
model = Person
47+
interfaces = (Node,)
48+
filterset_class = PersonFilterSet
49+
50+
3151
class Query(ObjectType):
3252
pets = DjangoFilterConnectionField(PetNode)
53+
people = DjangoFilterConnectionField(PersonNode)
3354

3455

3556
def test_string_in_filter():
@@ -61,6 +82,33 @@ def test_string_in_filter():
6182
]
6283

6384

85+
def test_string_in_filter_with_filterset_class():
86+
"""Test in filter on a string field with a custom filterset class."""
87+
Person.objects.create(name="John")
88+
Person.objects.create(name="Michael")
89+
Person.objects.create(name="Angela")
90+
91+
schema = Schema(query=Query)
92+
93+
query = """
94+
query {
95+
people (names: ["John", "Michael"]) {
96+
edges {
97+
node {
98+
name
99+
}
100+
}
101+
}
102+
}
103+
"""
104+
result = schema.execute(query)
105+
assert not result.errors
106+
assert result.data["people"]["edges"] == [
107+
{"node": {"name": "John"}},
108+
{"node": {"name": "Michael"}},
109+
]
110+
111+
64112
def test_int_in_filter():
65113
"""
66114
Test in filter on an integer field.

graphene_django/filter/utils.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ def get_filtering_args_from_filterset(filterset_class, type):
1919
model = filterset_class._meta.model
2020
for name, filter_field in six.iteritems(filterset_class.base_filters):
2121
form_field = None
22+
filter_type = filter_field.lookup_expr
2223

2324
if name in filterset_class.declared_filters:
2425
# Get the filter field from the explicitly declared filter
@@ -27,7 +28,6 @@ def get_filtering_args_from_filterset(filterset_class, type):
2728
else:
2829
# Get the filter field with no explicit type declaration
2930
model_field = get_model_field(model, filter_field.field_name)
30-
filter_type = filter_field.lookup_expr
3131
if filter_type != "isnull" and hasattr(model_field, "formfield"):
3232
form_field = model_field.formfield(
3333
required=filter_field.extra.get("required", False)
@@ -40,10 +40,11 @@ def get_filtering_args_from_filterset(filterset_class, type):
4040

4141
field = convert_form_field(form_field)
4242

43-
if filter_type in ["in", "range"]:
44-
# Replace CSV filters (`in`, `range`) argument type to be a list of the same type as the field.
45-
# See comments in `replace_csv_filters` method for more details.
46-
field = List(field.get_type())
43+
if filter_type in ["in", "range"]:
44+
# Replace CSV filters (`in`, `range`) argument type to be a list of
45+
# the same type as the field. See comments in
46+
# `replace_csv_filters` method for more details.
47+
field = List(field.get_type())
4748

4849
field_type = field.Argument()
4950
field_type.description = filter_field.label
@@ -79,10 +80,7 @@ def replace_csv_filters(filterset_class):
7980
"""
8081
for name, filter_field in six.iteritems(filterset_class.base_filters):
8182
filter_type = filter_field.lookup_expr
82-
if (
83-
filter_type in ["in", "range"]
84-
and name not in filterset_class.declared_filters
85-
):
83+
if filter_type in ["in", "range"]:
8684
assert isinstance(filter_field, BaseCSVFilter)
8785
filterset_class.base_filters[name] = Filter(
8886
field_name=filter_field.field_name,

graphene_django/tests/models.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
CHOICES = ((1, "this"), (2, _("that")))
77

88

9+
class Person(models.Model):
10+
name = models.CharField(max_length=30)
11+
12+
913
class Pet(models.Model):
1014
name = models.CharField(max_length=30)
1115
age = models.PositiveIntegerField()

0 commit comments

Comments
 (0)