Check for filters defined on base filterset classes (#730)

* Check for filters defined on base filterset classes

* Make python2.7 compatible and run black

* Add filter method and use filter in test

* Check article headline and reformat
This commit is contained in:
Kike Isidoro 2019-08-07 09:04:04 +02:00 committed by Jonathan Kim
parent 59f4f134b5
commit 6e137da469
2 changed files with 116 additions and 9 deletions

View File

@ -818,3 +818,106 @@ def test_integer_field_filter_type():
} }
""" """
) )
def test_filter_filterset_based_on_mixin():
class ArticleFilterMixin(FilterSet):
@classmethod
def get_filters(cls):
filters = super(FilterSet, cls).get_filters()
filters.update(
{
"viewer__email__in": django_filters.CharFilter(
method="filter_email_in", field_name="reporter__email__in"
)
}
)
return filters
def filter_email_in(cls, queryset, name, value):
return queryset.filter(**{name: [value]})
class NewArticleFilter(ArticleFilterMixin, ArticleFilter):
pass
class NewReporterNode(DjangoObjectType):
class Meta:
model = Reporter
interfaces = (Node,)
class NewArticleFilterNode(DjangoObjectType):
viewer = Field(NewReporterNode)
class Meta:
model = Article
interfaces = (Node,)
filterset_class = NewArticleFilter
def resolve_viewer(self, info):
return self.reporter
class Query(ObjectType):
all_articles = DjangoFilterConnectionField(NewArticleFilterNode)
reporter_1 = Reporter.objects.create(
first_name="John", last_name="Doe", email="john@doe.com"
)
article_1 = Article.objects.create(
headline="Hello",
reporter=reporter_1,
editor=reporter_1,
pub_date=datetime.now(),
pub_date_time=datetime.now(),
)
reporter_2 = Reporter.objects.create(
first_name="Adam", last_name="Doe", email="adam@doe.com"
)
article_2 = Article.objects.create(
headline="Good Bye",
reporter=reporter_2,
editor=reporter_2,
pub_date=datetime.now(),
pub_date_time=datetime.now(),
)
schema = Schema(query=Query)
query = (
"""
query NodeFilteringQuery {
allArticles(viewer_Email_In: "%s") {
edges {
node {
headline
viewer {
email
}
}
}
}
}
"""
% reporter_1.email
)
expected = {
"allArticles": {
"edges": [
{
"node": {
"headline": article_1.headline,
"viewer": {"email": reporter_1.email},
}
}
]
}
}
result = schema.execute(query)
assert not result.errors
assert result.data == expected

View File

@ -13,21 +13,25 @@ def get_filtering_args_from_filterset(filterset_class, type):
args = {} args = {}
model = filterset_class._meta.model model = filterset_class._meta.model
for name, filter_field in six.iteritems(filterset_class.base_filters): for name, filter_field in six.iteritems(filterset_class.base_filters):
form_field = None
if name in filterset_class.declared_filters: if name in filterset_class.declared_filters:
form_field = filter_field.field form_field = filter_field.field
else: else:
field_name = name.split("__", 1)[0] field_name = name.split("__", 1)[0]
model_field = model._meta.get_field(field_name)
if hasattr(model_field, "formfield"): if hasattr(model, field_name):
form_field = model_field.formfield( model_field = model._meta.get_field(field_name)
required=filter_field.extra.get("required", False)
)
# Fallback to field defined on filter if we can't get it from the if hasattr(model_field, "formfield"):
# model field form_field = model_field.formfield(
if not form_field: required=filter_field.extra.get("required", False)
form_field = filter_field.field )
# Fallback to field defined on filter if we can't get it from the
# model field
if not form_field:
form_field = filter_field.field
field_type = convert_form_field(form_field).Argument() field_type = convert_form_field(form_field).Argument()
field_type.description = filter_field.label field_type.description = filter_field.label