Skip to content

Commit 216c435

Browse files
author
Adam Charnock
committed
Further additions to docs for new django functionality
1 parent b44bae1 commit 216c435

File tree

3 files changed

+175
-9
lines changed

3 files changed

+175
-9
lines changed

docs/config.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ ga = "UA-12613282-7"
1616
"/docs/mutations/",
1717
"/docs/basic-types/",
1818
"/docs/relay/",
19+
"/docs/filtering/",
1920
]

docs/pages/docs/filtering.md

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
---
2+
title: Filtering (Django)
3+
description: Details of how to perform filtering
4+
---
5+
6+
# Filtering (Django)
7+
8+
Graphene integrates with [django-filter](https://django-filter.readthedocs.org)
9+
to provide filtering of results. See the
10+
[usage documentation](https://django-filter.readthedocs.org/en/latest/usage.html#the-filter)
11+
for details on the format for `filter_fields`.
12+
13+
**Note 1:** This filtering is only available when using the Django integrations
14+
(i.e. nodes which extend `DjangoNode`)
15+
16+
**Note 2:** `django-filter` is an optional dependency of Graphene. You will need to
17+
install it manually, which can be done as follows:
18+
19+
```bash
20+
pip install django-filter
21+
```
22+
23+
## Filterable fields
24+
25+
The `filter_fields` parameter is used to specify the fields which can be filtered upon.
26+
The value specified here is passed directly to `django-filter`, so see the
27+
[filtering documentation](https://django-filter.readthedocs.org/en/latest/usage.html#the-filter)
28+
for full details on the range of options available.
29+
30+
For example:
31+
32+
```python
33+
class AnimalNode(DjangoNode):
34+
class Meta:
35+
# Assume you have an Animal model defined with the following fields
36+
model = Animal
37+
filter_fields = ['name', 'genus', 'is_domesticated']
38+
39+
class Query(ObjectType):
40+
animal = relay.NodeField(AnimalNode)
41+
all_animals = DjangoFilterConnectionField(AnimalNode)
42+
```
43+
44+
You could then perform a query such as:
45+
46+
```graphql
47+
query {
48+
# Note that fields names become camelcased
49+
allAnimals(genus: "cat", isDomesticated: true) {
50+
edges {
51+
node {
52+
id,
53+
name
54+
}}}}
55+
```
56+
57+
You can also make more complex lookup types available:
58+
59+
```python
60+
class AnimalNode(DjangoNode):
61+
class Meta:
62+
model = Animal
63+
# Provide more complex lookup types
64+
filter_fields = {
65+
'name': ['exact', 'icontains', 'istartswith'],
66+
'genus': ['exact'],
67+
'is_domesticated': ['exact'],
68+
}
69+
```
70+
71+
Which you could query as follows:
72+
73+
```graphql
74+
query {
75+
# Note that fields names become camelcased
76+
allAnimals(nameIcontains: "lion") {
77+
edges {
78+
node {
79+
id,
80+
name
81+
}}}}
82+
```
83+
84+
## Orderable fields
85+
86+
Ordering can also be specified using `filter_order_by`. Like `filter_fields`,
87+
this value is also passed directly to `django-filter` as the `order_by` field.
88+
For full details see the
89+
[order_by documentation](https://django-filter.readthedocs.org/en/latest/usage.html#ordering-using-order-by).
90+
91+
For example:
92+
93+
```python
94+
class AnimalNode(DjangoNode):
95+
class Meta:
96+
model = Animal
97+
filter_fields = ['name', 'genus', 'is_domesticated']
98+
# Either a tuple/list of fields upon which ordering is allowed, or
99+
# True to allow filtering on all fields specified in filter_fields
100+
order_by_fields = True
101+
```
102+
103+
You can then control the ordering via the `orderBy` argument:
104+
105+
```graphql
106+
query {
107+
allAnimals(orderBy: "name") {
108+
edges {
109+
node {
110+
id,
111+
name
112+
}}}}
113+
```
114+
115+
## Custom Filtersets
116+
117+
By default Graphene provides easy access to the most commonly used
118+
features of `django-filter`. This is done by transparently creating a
119+
`django_filters.FilterSet` class for you and passing in the values for
120+
`filter_fields` and `order_by_fields`.
121+
122+
However, you may find this to be insufficient. In these cases you can
123+
create your own `Filterset` as follows:
124+
125+
```python
126+
class AnimalNode(DjangoNode):
127+
class Meta:
128+
# Assume you have an Animal model defined with the following fields
129+
model = Animal
130+
filter_fields = ['name', 'genus', 'is_domesticated']
131+
132+
133+
class AnimalFilter(django_filters.FilterSet):
134+
# Do case-insensitive lookups on 'name'
135+
name = django_filters.CharFilter(lookup_type='iexact')
136+
137+
class Meta:
138+
model = Animal
139+
fields = ['name', 'genus', 'is_domesticated']
140+
141+
142+
class Query(ObjectType):
143+
animal = relay.NodeField(AnimalNode)
144+
# We specify our custom AnimalFilter using the filterset_class param
145+
all_animals = DjangoFilterConnectionField(AnimalNode,
146+
filterset_class=AnimalFilter)
147+
```

docs/pages/docs/quickstart-django.md

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: Django Tutorial
2+
title: Django Quickstart
33
description: A Quick guide to Graphene in Django
44
---
55

@@ -71,12 +71,20 @@ class CategoryNode(DjangoNode):
7171
class Meta:
7272
model = Category
7373
filter_fields = ['name', 'ingredients']
74+
filter_order_by = ['name']
7475

7576

7677
class IngredientNode(DjangoNode):
7778
class Meta:
7879
model = Ingredient
79-
filter_fields = ['name', 'notes', 'category']
80+
# Allow for some more advanced filtering here
81+
filter_fields = {
82+
'name': ['exact', 'icontains', 'istartswith'],
83+
'notes': ['exact', 'icontains'],
84+
'category': ['exact'],
85+
'category__name': ['exact'],
86+
}
87+
filter_order_by = ['name', 'category__name']
8088

8189

8290
class Query(ObjectType):
@@ -90,6 +98,11 @@ class Query(ObjectType):
9098
abstract = True
9199
```
92100

101+
The filtering functionality is provided by
102+
[django-filter](https://django-filter.readthedocs.org). See the
103+
[usage documentation](https://django-filter.readthedocs.org/en/latest/usage.html#the-filter)
104+
for details on the format for `filter_fields`.
105+
93106
Note that the above `Query` class is marked as 'abstract'. This is because we
94107
want will now create a project-level query which will combine all our app-level
95108
queries.
@@ -225,12 +238,17 @@ query {
225238
edges {
226239
node {
227240
name
228-
}
229-
}
230-
}
241+
}}}}}}}
242+
```
231243

232-
}
233-
}
234-
}
235-
}
244+
Or you can get only 'meat' ingredients containing the letter 'e':
245+
246+
```graphql
247+
query {
248+
# You can also use `category: "CATEGORY GLOBAL ID"`
249+
allIngredients(nameIcontains: "e", categoryName: "Meat") {
250+
edges {
251+
node {
252+
name
253+
}}}}
236254
```

0 commit comments

Comments
 (0)