Skip to content

Commit 4925882

Browse files
committed
DjangoFilterConnectionField now accepts fields, order_by, and extra_filter_meta
1 parent 7bfeb08 commit 4925882

File tree

2 files changed

+62
-2
lines changed

2 files changed

+62
-2
lines changed

graphene/contrib/django/fields.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import warnings
22

33
import six
4-
4+
from django_filters import FilterSet
55

66
from ...core.exceptions import SkipField
77
from ...core.fields import Field
@@ -66,12 +66,36 @@ def get_object_type(self, schema):
6666
return get_type_for_model(schema, self.model)
6767

6868

69+
def custom_filterset_factory(model, filter_base_class=FilterSet, **meta):
70+
meta.update({
71+
'model': model,
72+
})
73+
meta_class = type(str('Meta'), (object,), meta)
74+
filterset = type(str('%sFilterSet' % model._meta.object_name),
75+
(filter_base_class,), {'Meta': meta_class})
76+
return filterset
77+
78+
6979
class DjangoFilterConnectionField(DjangoConnectionField):
7080

71-
def __init__(self, type, filterset_class, resolver=None, on=None, *args, **kwargs):
81+
def __init__(self, type, filterset_class=None, resolver=None, on=None,
82+
fields=None, order_by=None, extra_filter_meta=None,
83+
*args, **kwargs):
7284
if not resolver:
7385
resolver = FilterConnectionResolver(type, on, filterset_class)
7486

87+
if not filterset_class:
88+
# If no filter class is specified then create one given the
89+
# information provided
90+
meta = dict(
91+
model=type._meta.model,
92+
fields=fields,
93+
order_by=order_by,
94+
)
95+
if extra_filter_meta:
96+
meta.update(extra_filter_meta)
97+
filterset_class = custom_filterset_factory(**meta)
98+
7599
kwargs.setdefault('args', {})
76100
kwargs['args'].update(**self.get_filtering_args(type, filterset_class))
77101
super(DjangoFilterConnectionField, self).__init__(type, resolver, *args, **kwargs)

graphene/contrib/django/tests/test_fields.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,47 @@ def test_filter_explicit_filterset_arguments():
4646
)
4747

4848

49+
def test_filter_shortcut_filterset_arguments_list():
50+
field = DjangoFilterConnectionField(ArticleNode, fields=['pub_date', 'reporter'])
51+
assert_arguments(field,
52+
'pubDate',
53+
'reporter',
54+
)
55+
56+
57+
def test_filter_shortcut_filterset_arguments_dict():
58+
field = DjangoFilterConnectionField(ArticleNode, fields={
59+
'headline': ['exact', 'icontains'],
60+
'reporter': ['exact'],
61+
})
62+
assert_arguments(field,
63+
'headline', 'headlineIcontains',
64+
'reporter',
65+
)
66+
67+
4968
def test_filter_explicit_filterset_orderable():
5069
field = DjangoFilterConnectionField(ArticleNode, filterset_class=ArticleFilter)
5170
assert_orderable(field)
5271

5372

73+
def test_filter_shortcut_filterset_orderable_true():
74+
field = DjangoFilterConnectionField(ArticleNode, order_by=True)
75+
assert_orderable(field)
76+
77+
78+
def test_filter_shortcut_filterset_orderable_headline():
79+
field = DjangoFilterConnectionField(ArticleNode, order_by=['headline'])
80+
assert_orderable(field)
81+
82+
5483
def test_filter_explicit_filterset_not_orderable():
5584
field = DjangoFilterConnectionField(PetNode, filterset_class=PetFilter)
5685
assert_not_orderable(field)
86+
87+
88+
def test_filter_shortcut_filterset_extra_meta():
89+
field = DjangoFilterConnectionField(ArticleNode, extra_filter_meta={
90+
'ordering': True
91+
})
92+
assert_orderable(field)

0 commit comments

Comments
 (0)