Filtering🔗
ModelFilterSet🔗
A custom FilterSet class for optimizing the filtering of GraphQL queries.
from graphene_django_extensions import ModelFilterSet
from example.models import Example
class ExampleFilterSet(ModelFilterSet):
class Meta:
model = Example
fields = [...]
Extends django_filters.filterset.FilterSet
and adds the following features:
- Automatically a
order_by = CustomOrderingFilter(fields=["pk"])
to the class for ordering the filterset. - Changes the default filters for all relationships (
one-to-one
,many-to-one
, etc.) to not make a database queries to check if the filtered rows exists.
Subclasses can be configured through the Meta
-class. Here are the most useful options:
Option | Type | Description |
---|---|---|
model |
type[Model] |
Required. The model class for the filterset. |
fields |
list[str] or dict[str, list[str]] or __all__ |
Required. The fields to include in the node. If __all__ is used, all fields are included. |
order_by |
list[str] or list[tuple[str, str]] |
Optional. Ordering filters to add to the filterset. Can also add non-field orderings, or customize field orderings by adding a order_by_{field_name} method to the ModelFilterSet subclass. |
combination_methods |
list[str] |
Optional. Allows combining method filters so that they will use the same filter function. The combination method will always run, and its value will be a mapping of the field names of the combined filters to their values. |
CustomOrderingFilter🔗
Extends django_filters.filters.OrderingFilter
by adding option for custom orderings
by defining order_by_{name}
functions on its subclasses or filtersets it is defined on.
This filter is automatically added to ModelFilterSet
subclasses, and its Meta.order_by
can be used to add custom orderings.
from graphene_django_extensions import ModelFilterSet
class ExampleFilterSet(ModelFilterSet):
class Meta:
model = Example
fields = [...]
order_by = ["name"]
def order_by_name(self, qs: QuerySet, desc: bool) -> QuerySet:
return qs.order_by("-name" if desc else "name")
Additionally, the ordering choices are converted to GraphQL enums (e.g. "name"
-> nameAsc
& "-name"
-> nameDesc
), which gives better autocomplete results in GraphiQL, and makes the
available orderings more explicit.
UserDefinedFilter🔗
A filter which allows users to define custom filtering rules for a set of predefined model fields. The idea is similar in concept to the GraphQL itself; allowing users to select which data they actually need vs. what has been predefined.
from graphene_django_extensions.filters import ModelFilterSet, UserDefinedFilter
class ExampleFilterSet(ModelFilterSet):
filter = UserDefinedFilter(
model=Example,
fields=["name", "number", "email"],
)
Given the above filter, the user can define the following filter:
query {
examples(
filter: {
field: name,
operation: CONTAINS,
value: "foo",
}
) {
edges {
node {
pk
}
}
}
}
This creates a simple Q(name__contains="foo")
filter for the queryset.
Notice that the field
values are enums created from the defined fields in the UserDefinedFilter.
If no fields are given, all fields from the given model can be filtered on. Related fields can also be
added via the "__" lookup syntax. Filter aliases can be given by specifying a tuple of
("field_lookup", "alias")
in the fields list.
The model argument is mandatory, and is used to rename the filter input type after the field
enum field
has been added to it (in additions fetching the default fields if no fields are defined).
Let's see a more complex example:
query {
examples(
filter: {
operation: AND,
operations: [
{
operation: OR,
operations: [
{
field: name,
operation: CONTAINS,
value: "foo",
},
{
field: email,
operation: CONTAINS,
value: "foo",
},
],
},
{
operation: NOT,
operations: [
{
field: number,
operation: LT,
value: 10,
}
]
},
],
}
) {
edges {
node {
pk
}
}
}
}
This configuration corresponds to (Q(name__contains="foo") | Q(email__contains="foo") & ~Q(number__lt=10))
.
As the above example demonstrates, logical operations can also be used, allowing for complex filtering rules to be defined, which regular filter fields cannot do.
EnumChoiceFilter & EnumMultipleChoiceFilter🔗
Custom fields for handling enums better in GraphQL filters.
Using django_filters.ChoiceFilter
causes the Enums to be converted to strings in GraphQL filters.
This class uses GraphQL Enums instead, which gives better autocomplete results.
IntegerChoiceFilter & IntegerMultipleChoiceFilter🔗
Allows plain integers as choices in GraphQL filters. Normally, integer enums are converted
to string enums in GraphQL by prefixing them with A_
, but this filter allows using plain integers.