0
# Filtering Integration
1
2
Django-filter integration for advanced GraphQL field filtering with automatic filter generation, custom filter support, and seamless integration with Django QuerySets. Provides powerful filtering capabilities for GraphQL APIs with minimal configuration.
3
4
## Capabilities
5
6
### DjangoFilterConnectionField
7
8
Connection field with django-filter integration that automatically generates GraphQL arguments from Django model fields and FilterSet classes.
9
10
```python { .api }
11
class DjangoFilterConnectionField(DjangoConnectionField):
12
"""
13
Connection field with django-filter integration.
14
15
Automatically generates GraphQL filtering arguments from Django model
16
fields or custom FilterSet classes with Relay-style pagination support.
17
"""
18
19
def __init__(self, type, fields=None, filterset_class=None,
20
extra_filter_meta=None, max_limit=None,
21
enforce_first_or_last=False, **kwargs):
22
"""
23
Initialize filter connection field.
24
25
Parameters:
26
- type: GraphQL connection type
27
- fields: Fields to filter on (dict or list)
28
- filterset_class: Custom django_filters.FilterSet class
29
- extra_filter_meta: Additional FilterSet metadata
30
- max_limit: Maximum pagination limit
31
- enforce_first_or_last: Require first/last arguments
32
- **kwargs: Additional connection options
33
"""
34
35
@property
36
def filterset_class(self):
37
"""
38
Get or create FilterSet class for this field.
39
40
Returns:
41
django_filters.FilterSet: FilterSet class for filtering
42
"""
43
44
@property
45
def filtering_args(self):
46
"""
47
Get GraphQL arguments for filtering.
48
49
Returns:
50
dict: Mapping of argument names to GraphQL argument types
51
"""
52
53
@classmethod
54
def resolve_queryset(cls, connection, queryset, info, args):
55
"""
56
Resolve queryset with filtering applied.
57
58
Parameters:
59
- connection: Connection instance
60
- queryset: Django QuerySet
61
- info: GraphQL execution info
62
- args: Filter arguments
63
64
Returns:
65
QuerySet: Filtered queryset
66
"""
67
```
68
69
### Filter Classes
70
71
Specialized filter classes for GraphQL-specific filtering requirements with support for global IDs, arrays, and complex data types.
72
73
```python { .api }
74
class GlobalIDFilter(django_filters.Filter):
75
"""Filter by global ID with automatic ID decoding."""
76
77
def filter(self, qs, value):
78
"""
79
Filter queryset by global ID.
80
81
Parameters:
82
- qs: Django QuerySet
83
- value: Global ID value
84
85
Returns:
86
QuerySet: Filtered queryset
87
"""
88
89
class GlobalIDMultipleChoiceFilter(django_filters.MultipleChoiceFilter):
90
"""Multiple choice filter for global IDs."""
91
92
def filter(self, qs, value):
93
"""
94
Filter queryset by multiple global IDs.
95
96
Parameters:
97
- qs: Django QuerySet
98
- value: List of global ID values
99
100
Returns:
101
QuerySet: Filtered queryset
102
"""
103
104
class ArrayFilter(django_filters.Filter):
105
"""Filter array fields (PostgreSQL specific)."""
106
107
class ListFilter(django_filters.Filter):
108
"""List-based filtering for multiple values."""
109
110
class RangeFilter(django_filters.Filter):
111
"""Range-based filtering for numeric and date fields."""
112
113
class TypedFilter(django_filters.Filter):
114
"""Type-aware filtering with automatic type conversion."""
115
```
116
117
## Usage Examples
118
119
### Basic Filtering Setup
120
121
```python
122
from django.db import models
123
from graphene_django import DjangoObjectType
124
from graphene_django.filter import DjangoFilterConnectionField
125
import graphene
126
127
class User(models.Model):
128
username = models.CharField(max_length=150)
129
email = models.EmailField()
130
is_active = models.BooleanField(default=True)
131
created_at = models.DateTimeField(auto_now_add=True)
132
133
class UserType(DjangoObjectType):
134
class Meta:
135
model = User
136
fields = '__all__'
137
filter_fields = ['username', 'email', 'is_active']
138
139
class Query(graphene.ObjectType):
140
users = DjangoFilterConnectionField(UserType)
141
142
# GraphQL query with filtering:
143
# query {
144
# users(username: "john", isActive: true) {
145
# edges {
146
# node {
147
# id
148
# username
149
150
# }
151
# }
152
# }
153
# }
154
```
155
156
### Advanced Filter Configuration
157
158
```python
159
class UserType(DjangoObjectType):
160
class Meta:
161
model = User
162
fields = '__all__'
163
filter_fields = {
164
'username': ['exact', 'icontains', 'istartswith'],
165
'email': ['exact', 'icontains'],
166
'is_active': ['exact'],
167
'created_at': ['exact', 'gte', 'lte', 'year', 'month']
168
}
169
170
# Generated GraphQL arguments:
171
# users(
172
# username: String
173
# username_Icontains: String
174
# username_Istartswith: String
175
# email: String
176
# email_Icontains: String
177
# isActive: Boolean
178
# createdAt: DateTime
179
# createdAt_Gte: DateTime
180
# createdAt_Lte: DateTime
181
# createdAt_Year: Int
182
# createdAt_Month: Int
183
# )
184
```
185
186
### Custom FilterSet Class
187
188
```python
189
import django_filters
190
from django_filters import FilterSet
191
192
class UserFilterSet(FilterSet):
193
name = django_filters.CharFilter(method='filter_full_name')
194
created_after = django_filters.DateTimeFilter(
195
field_name='created_at',
196
lookup_expr='gte'
197
)
198
199
class Meta:
200
model = User
201
fields = ['username', 'is_active']
202
203
def filter_full_name(self, queryset, name, value):
204
return queryset.filter(
205
models.Q(first_name__icontains=value) |
206
models.Q(last_name__icontains=value)
207
)
208
209
class UserType(DjangoObjectType):
210
class Meta:
211
model = User
212
fields = '__all__'
213
filterset_class = UserFilterSet
214
215
class Query(graphene.ObjectType):
216
users = DjangoFilterConnectionField(UserType)
217
```
218
219
### Relationship Filtering
220
221
```python
222
class Post(models.Model):
223
title = models.CharField(max_length=200)
224
author = models.ForeignKey(User, on_delete=models.CASCADE)
225
created_at = models.DateTimeField(auto_now_add=True)
226
published = models.BooleanField(default=False)
227
228
class PostType(DjangoObjectType):
229
class Meta:
230
model = Post
231
fields = '__all__'
232
filter_fields = {
233
'title': ['exact', 'icontains'],
234
'author': ['exact'],
235
'author__username': ['exact', 'icontains'],
236
'published': ['exact'],
237
'created_at': ['gte', 'lte']
238
}
239
240
# GraphQL query filtering by relationship:
241
# query {
242
# posts(author_Username_Icontains: "john", published: true) {
243
# edges {
244
# node {
245
# title
246
# author { username }
247
# }
248
# }
249
# }
250
# }
251
```
252
253
### Global ID Filtering
254
255
```python
256
from graphene_django.filter.filters import GlobalIDFilter
257
258
class PostFilterSet(FilterSet):
259
author_id = GlobalIDFilter(field_name='author')
260
261
class Meta:
262
model = Post
263
fields = ['title', 'published']
264
265
class PostType(DjangoObjectType):
266
class Meta:
267
model = Post
268
fields = '__all__'
269
filterset_class = PostFilterSet
270
271
# GraphQL query with global ID:
272
# query {
273
# posts(authorId: "VXNlclR5cGU6MQ==") {
274
# edges {
275
# node {
276
# title
277
# }
278
# }
279
# }
280
# }
281
```
282
283
### Combining Filtering with Custom Resolution
284
285
```python
286
class Query(graphene.ObjectType):
287
my_posts = DjangoFilterConnectionField(PostType)
288
289
def resolve_my_posts(self, info, **args):
290
# Start with user's posts
291
queryset = Post.objects.filter(author=info.context.user)
292
293
# Apply django-filter filtering
294
filter_set = PostType._meta.filterset_class(
295
args,
296
queryset=queryset
297
)
298
return filter_set.qs
299
```
300
301
### Custom Filter Field Types
302
303
```python
304
from graphene_django.filter.filters import ArrayFilter
305
306
class TagFilterSet(FilterSet):
307
tags = ArrayFilter(field_name='tags__name', lookup_expr='contains')
308
309
class Meta:
310
model = Post
311
fields = ['title']
312
313
# For PostgreSQL ArrayField filtering:
314
# query {
315
# posts(tags: ["python", "django"]) {
316
# edges {
317
# node {
318
# title
319
# tags
320
# }
321
# }
322
# }
323
# }
324
```
325
326
### Filter Field Ordering
327
328
```python
329
class UserFilterSet(FilterSet):
330
order_by = django_filters.OrderingFilter(
331
fields=(
332
('created_at', 'created'),
333
('username', 'username'),
334
('email', 'email'),
335
)
336
)
337
338
class Meta:
339
model = User
340
fields = ['is_active']
341
342
# GraphQL query with ordering:
343
# query {
344
# users(orderBy: "-created") {
345
# edges {
346
# node {
347
# username
348
# createdAt
349
# }
350
# }
351
# }
352
# }
353
```