9
9
from graphene .relay import Node
10
10
from graphene_django import DjangoObjectType
11
11
from graphene_django .utils import DJANGO_FILTER_INSTALLED
12
+ from graphene_django .filter import ArrayFilter , ListFilter
12
13
13
14
from ...compat import ArrayField
14
15
@@ -32,27 +33,37 @@ def Event():
32
33
class Event (models .Model ):
33
34
name = models .CharField (max_length = 50 )
34
35
tags = ArrayField (models .CharField (max_length = 50 ))
36
+ tag_ids = ArrayField (models .IntegerField ())
37
+ random_field = ArrayField (models .BooleanField ())
35
38
36
39
return Event
37
40
38
41
39
42
@pytest .fixture
40
43
def EventFilterSet (Event ):
41
-
42
- from django .contrib .postgres .forms import SimpleArrayField
43
-
44
- class ArrayFilter (filters .Filter ):
45
- base_field_class = SimpleArrayField
46
-
47
44
class EventFilterSet (FilterSet ):
48
45
class Meta :
49
46
model = Event
50
47
fields = {
51
- "name" : ["exact" ],
48
+ "name" : ["exact" , "contains" ],
52
49
}
53
50
51
+ # Those are actually usable with our Query fixture bellow
54
52
tags__contains = ArrayFilter (field_name = "tags" , lookup_expr = "contains" )
55
53
tags__overlap = ArrayFilter (field_name = "tags" , lookup_expr = "overlap" )
54
+ tags = ArrayFilter (field_name = "tags" , lookup_expr = "exact" )
55
+
56
+ # Those are actually not usable and only to check type declarations
57
+ tags_ids__contains = ArrayFilter (field_name = "tag_ids" , lookup_expr = "contains" )
58
+ tags_ids__overlap = ArrayFilter (field_name = "tag_ids" , lookup_expr = "overlap" )
59
+ tags_ids = ArrayFilter (field_name = "tag_ids" , lookup_expr = "exact" )
60
+ random_field__contains = ArrayFilter (
61
+ field_name = "random_field" , lookup_expr = "contains"
62
+ )
63
+ random_field__overlap = ArrayFilter (
64
+ field_name = "random_field" , lookup_expr = "overlap"
65
+ )
66
+ random_field = ArrayFilter (field_name = "random_field" , lookup_expr = "exact" )
56
67
57
68
return EventFilterSet
58
69
@@ -70,6 +81,11 @@ class Meta:
70
81
71
82
@pytest .fixture
72
83
def Query (Event , EventType ):
84
+ """
85
+ Note that we have to use a custom resolver to replicate the arrayfield filter behavior as
86
+ we are running unit tests in sqlite which does not have ArrayFields.
87
+ """
88
+
73
89
class Query (graphene .ObjectType ):
74
90
events = DjangoFilterConnectionField (EventType )
75
91
@@ -79,6 +95,7 @@ def resolve_events(self, info, **kwargs):
79
95
Event (name = "Live Show" , tags = ["concert" , "music" , "rock" ],),
80
96
Event (name = "Musical" , tags = ["movie" , "music" ],),
81
97
Event (name = "Ballet" , tags = ["concert" , "dance" ],),
98
+ Event (name = "Speech" , tags = [],),
82
99
]
83
100
84
101
STORE ["events" ] = events
@@ -105,6 +122,13 @@ def filter_events(**kwargs):
105
122
STORE ["events" ],
106
123
)
107
124
)
125
+ if "tags__exact" in kwargs :
126
+ STORE ["events" ] = list (
127
+ filter (
128
+ lambda e : set (kwargs ["tags__exact" ]) == set (e .tags ),
129
+ STORE ["events" ],
130
+ )
131
+ )
108
132
109
133
def mock_queryset_filter (* args , ** kwargs ):
110
134
filter_events (** kwargs )
@@ -121,7 +145,9 @@ def mock_queryset_count(*args, **kwargs):
121
145
m_queryset .filter .side_effect = mock_queryset_filter
122
146
m_queryset .none .side_effect = mock_queryset_none
123
147
m_queryset .count .side_effect = mock_queryset_count
124
- m_queryset .__getitem__ .side_effect = STORE ["events" ].__getitem__
148
+ m_queryset .__getitem__ .side_effect = lambda index : STORE [
149
+ "events"
150
+ ].__getitem__ (index )
125
151
126
152
return m_queryset
127
153
0 commit comments