Skip to content

Commit fb45a83

Browse files
committed
Moving django-filter dependent code into graphene.contrib.django.filter
Graphene should now run fine without django-filter. Tests will also run without django-filter. However, I'm leaving it as a requirement in setup.py's `tests_require` setting as testing without it is probably not to be encouraged.
1 parent 3709f94 commit fb45a83

File tree

13 files changed

+190
-170
lines changed

13 files changed

+190
-170
lines changed

graphene/contrib/django/__init__.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@
55
)
66
from graphene.contrib.django.fields import (
77
DjangoConnectionField,
8-
DjangoModelField,
9-
DjangoFilterConnectionField
8+
DjangoModelField
109
)
1110

1211
__all__ = ['DjangoObjectType', 'DjangoNode', 'DjangoConnection',
13-
'DjangoConnectionField', 'DjangoModelField',
14-
'DjangoFilterConnectionField']
12+
'DjangoModelField']

graphene/contrib/django/fields.py

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

3-
from graphene.contrib.django.utils import get_filtering_args_from_filterset
4-
from .resolvers import FilterConnectionResolver
53
from .utils import get_type_for_model
64
from ...core.exceptions import SkipField
75
from ...core.fields import Field
@@ -62,23 +60,3 @@ def get_object_type(self, schema):
6260
return get_type_for_model(schema, self.model)
6361

6462

65-
class DjangoFilterConnectionField(DjangoConnectionField):
66-
67-
def __init__(self, type, on=None, fields=None, order_by=None,
68-
extra_filter_meta=None, filterset_class=None, resolver=None,
69-
*args, **kwargs):
70-
71-
if not resolver:
72-
resolver = FilterConnectionResolver(
73-
node=type,
74-
on=on,
75-
filterset_class=filterset_class,
76-
fields=fields,
77-
order_by=order_by,
78-
extra_filter_meta=extra_filter_meta,
79-
)
80-
81-
filtering_args = get_filtering_args_from_filterset(resolver.get_filterset_class(), type)
82-
kwargs.setdefault('args', {})
83-
kwargs['args'].update(**filtering_args)
84-
super(DjangoFilterConnectionField, self).__init__(type, resolver, *args, **kwargs)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from .fields import DjangoFilterConnectionField
2+
from .filterset import GrapheneFilterSet, GlobalIDFilter
3+
from .resolvers import FilterConnectionResolver
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from graphene.contrib.django import DjangoConnectionField
2+
from graphene.contrib.django.filter.resolvers import FilterConnectionResolver
3+
from graphene.contrib.django.utils import get_filtering_args_from_filterset
4+
5+
6+
class DjangoFilterConnectionField(DjangoConnectionField):
7+
8+
def __init__(self, type, on=None, fields=None, order_by=None,
9+
extra_filter_meta=None, filterset_class=None, resolver=None,
10+
*args, **kwargs):
11+
12+
if not resolver:
13+
resolver = FilterConnectionResolver(
14+
node=type,
15+
on=on,
16+
filterset_class=filterset_class,
17+
fields=fields,
18+
order_by=order_by,
19+
extra_filter_meta=extra_filter_meta,
20+
)
21+
22+
filtering_args = get_filtering_args_from_filterset(resolver.get_filterset_class(), type)
23+
kwargs.setdefault('args', {})
24+
kwargs['args'].update(**filtering_args)
25+
super(DjangoFilterConnectionField, self).__init__(type, resolver, *args, **kwargs)
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
from django.core.exceptions import ImproperlyConfigured
2+
3+
from graphene.contrib.django.filter.filterset import setup_filterset, custom_filterset_factory
4+
from graphene.contrib.django.resolvers import BaseQuerySetConnectionResolver
5+
6+
7+
class FilterConnectionResolver(BaseQuerySetConnectionResolver):
8+
# Querying using django-filter
9+
10+
def __init__(self, node, on=None, filterset_class=None,
11+
fields=None, order_by=None, extra_filter_meta=None):
12+
self.filterset_class = filterset_class
13+
self.fields = fields
14+
self.order_by = order_by
15+
self.extra_filter_meta = extra_filter_meta or {}
16+
self._filterset_class = None
17+
super(FilterConnectionResolver, self).__init__(node, on)
18+
19+
def make_query(self):
20+
filterset_class = self.get_filterset_class()
21+
filterset = self.get_filterset(filterset_class)
22+
return filterset.qs
23+
24+
def get_filterset_class(self):
25+
"""Get the class to be used as the FilterSet"""
26+
if self._filterset_class:
27+
return self._filterset_class
28+
29+
if self.filterset_class:
30+
# If were given a FilterSet class, then set it up and
31+
# return it
32+
self._filterset_class = setup_filterset(self.filterset_class)
33+
elif self.model:
34+
# If no filter class was specified then create one given the
35+
# other information provided
36+
meta = dict(
37+
model=self.model,
38+
fields=self.fields,
39+
order_by=self.order_by,
40+
)
41+
meta.update(self.extra_filter_meta)
42+
self._filterset_class = custom_filterset_factory(**meta)
43+
else:
44+
msg = "Neither 'filterset_class' or 'model' available in '%s'. " \
45+
"Either pass in 'filterset_class' or 'model' when " \
46+
"initialising, or extend this class and override " \
47+
"get_filterset() or get_filterset_class()"
48+
raise ImproperlyConfigured(msg % self.__class__.__name__)
49+
50+
return self._filterset_class
51+
52+
def get_filterset(self, filterset_class):
53+
"""Get an instance of the FilterSet"""
54+
kwargs = self.get_filterset_kwargs(filterset_class)
55+
return filterset_class(**kwargs)
56+
57+
def get_filterset_kwargs(self, filterset_class):
58+
"""Get the kwargs to use when initialising the FilterSet class"""
59+
kwargs = {
60+
'data': self.args or None,
61+
'queryset': self.get_manager()
62+
}
63+
return kwargs

graphene/contrib/django/resolvers.py

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
from django.core.exceptions import ImproperlyConfigured
2-
3-
from graphene.contrib.django.filterset import setup_filterset, custom_filterset_factory
4-
5-
61
class BaseQuerySetConnectionResolver(object):
72

83
def __init__(self, node, on=None):
@@ -48,60 +43,3 @@ def get_order(self):
4843
return self.args.get('order', None)
4944

5045

51-
class FilterConnectionResolver(BaseQuerySetConnectionResolver):
52-
# Querying using django-filter
53-
54-
def __init__(self, node, on=None, filterset_class=None,
55-
fields=None, order_by=None, extra_filter_meta=None):
56-
self.filterset_class = filterset_class
57-
self.fields = fields
58-
self.order_by = order_by
59-
self.extra_filter_meta = extra_filter_meta or {}
60-
self._filterset_class = None
61-
super(FilterConnectionResolver, self).__init__(node, on)
62-
63-
def make_query(self):
64-
filterset_class = self.get_filterset_class()
65-
filterset = self.get_filterset(filterset_class)
66-
return filterset.qs
67-
68-
def get_filterset_class(self):
69-
"""Get the class to be used as the FilterSet"""
70-
if self._filterset_class:
71-
return self._filterset_class
72-
73-
if self.filterset_class:
74-
# If were given a FilterSet class, then set it up and
75-
# return it
76-
self._filterset_class = setup_filterset(self.filterset_class)
77-
elif self.model:
78-
# If no filter class was specified then create one given the
79-
# other information provided
80-
meta = dict(
81-
model=self.model,
82-
fields=self.fields,
83-
order_by=self.order_by,
84-
)
85-
meta.update(self.extra_filter_meta)
86-
self._filterset_class = custom_filterset_factory(**meta)
87-
else:
88-
msg = "Neither 'filterset_class' or 'model' available in '%s'. " \
89-
"Either pass in 'filterset_class' or 'model' when " \
90-
"initialising, or extend this class and override " \
91-
"get_filterset() or get_filterset_class()"
92-
raise ImproperlyConfigured(msg % self.__class__.__name__)
93-
94-
return self._filterset_class
95-
96-
def get_filterset(self, filterset_class):
97-
"""Get an instance of the FilterSet"""
98-
kwargs = self.get_filterset_kwargs(filterset_class)
99-
return filterset_class(**kwargs)
100-
101-
def get_filterset_kwargs(self, filterset_class):
102-
"""Get the kwargs to use when initialising the FilterSet class"""
103-
kwargs = {
104-
'data': self.args or None,
105-
'queryset': self.get_manager()
106-
}
107-
return kwargs

graphene/contrib/django/tests/filter/__init__.py

Whitespace-only changes.

graphene/contrib/django/tests/filters.py renamed to graphene/contrib/django/tests/filter/filters.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import django_filters
22

33
from graphene.contrib.django.tests.models import Reporter
4-
from .models import Article, Pet
4+
from graphene.contrib.django.tests.models import Article, Pet
55

66

77
class ArticleFilter(django_filters.FilterSet):

graphene/contrib/django/tests/test_fields.py renamed to graphene/contrib/django/tests/filter/test_fields.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1-
import django_filters
1+
import pytest
22

3-
from graphene.contrib.django import DjangoFilterConnectionField, DjangoNode
4-
from graphene.contrib.django.filterset import GlobalIDFilter
3+
try:
4+
import django_filters
5+
except ImportError:
6+
pytestmark = pytest.mark.skipif(True, reason='django_filters not installed')
7+
else:
8+
from graphene.contrib.django.filter import GlobalIDFilter, DjangoFilterConnectionField
9+
from graphene.contrib.django.tests.filter.filters import ArticleFilter, PetFilter
10+
11+
from graphene.contrib.django import DjangoNode
512
from graphene.contrib.django.forms import GlobalIDFormField
6-
from graphene.contrib.django.tests.filters import ArticleFilter, PetFilter
713
from graphene.contrib.django.tests.models import Article, Pet
814

915

0 commit comments

Comments
 (0)