Django integration for Graphene enabling GraphQL APIs in Django applications
—
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.
Connection field with django-filter integration that automatically generates GraphQL arguments from Django model fields and FilterSet classes.
class DjangoFilterConnectionField(DjangoConnectionField):
"""
Connection field with django-filter integration.
Automatically generates GraphQL filtering arguments from Django model
fields or custom FilterSet classes with Relay-style pagination support.
"""
def __init__(self, type, fields=None, filterset_class=None,
extra_filter_meta=None, max_limit=None,
enforce_first_or_last=False, **kwargs):
"""
Initialize filter connection field.
Parameters:
- type: GraphQL connection type
- fields: Fields to filter on (dict or list)
- filterset_class: Custom django_filters.FilterSet class
- extra_filter_meta: Additional FilterSet metadata
- max_limit: Maximum pagination limit
- enforce_first_or_last: Require first/last arguments
- **kwargs: Additional connection options
"""
@property
def filterset_class(self):
"""
Get or create FilterSet class for this field.
Returns:
django_filters.FilterSet: FilterSet class for filtering
"""
@property
def filtering_args(self):
"""
Get GraphQL arguments for filtering.
Returns:
dict: Mapping of argument names to GraphQL argument types
"""
@classmethod
def resolve_queryset(cls, connection, queryset, info, args):
"""
Resolve queryset with filtering applied.
Parameters:
- connection: Connection instance
- queryset: Django QuerySet
- info: GraphQL execution info
- args: Filter arguments
Returns:
QuerySet: Filtered queryset
"""Specialized filter classes for GraphQL-specific filtering requirements with support for global IDs, arrays, and complex data types.
class GlobalIDFilter(django_filters.Filter):
"""Filter by global ID with automatic ID decoding."""
def filter(self, qs, value):
"""
Filter queryset by global ID.
Parameters:
- qs: Django QuerySet
- value: Global ID value
Returns:
QuerySet: Filtered queryset
"""
class GlobalIDMultipleChoiceFilter(django_filters.MultipleChoiceFilter):
"""Multiple choice filter for global IDs."""
def filter(self, qs, value):
"""
Filter queryset by multiple global IDs.
Parameters:
- qs: Django QuerySet
- value: List of global ID values
Returns:
QuerySet: Filtered queryset
"""
class ArrayFilter(django_filters.Filter):
"""Filter array fields (PostgreSQL specific)."""
class ListFilter(django_filters.Filter):
"""List-based filtering for multiple values."""
class RangeFilter(django_filters.Filter):
"""Range-based filtering for numeric and date fields."""
class TypedFilter(django_filters.Filter):
"""Type-aware filtering with automatic type conversion."""from django.db import models
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField
import graphene
class User(models.Model):
username = models.CharField(max_length=150)
email = models.EmailField()
is_active = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
class UserType(DjangoObjectType):
class Meta:
model = User
fields = '__all__'
filter_fields = ['username', 'email', 'is_active']
class Query(graphene.ObjectType):
users = DjangoFilterConnectionField(UserType)
# GraphQL query with filtering:
# query {
# users(username: "john", isActive: true) {
# edges {
# node {
# id
# username
# email
# }
# }
# }
# }class UserType(DjangoObjectType):
class Meta:
model = User
fields = '__all__'
filter_fields = {
'username': ['exact', 'icontains', 'istartswith'],
'email': ['exact', 'icontains'],
'is_active': ['exact'],
'created_at': ['exact', 'gte', 'lte', 'year', 'month']
}
# Generated GraphQL arguments:
# users(
# username: String
# username_Icontains: String
# username_Istartswith: String
# email: String
# email_Icontains: String
# isActive: Boolean
# createdAt: DateTime
# createdAt_Gte: DateTime
# createdAt_Lte: DateTime
# createdAt_Year: Int
# createdAt_Month: Int
# )import django_filters
from django_filters import FilterSet
class UserFilterSet(FilterSet):
name = django_filters.CharFilter(method='filter_full_name')
created_after = django_filters.DateTimeFilter(
field_name='created_at',
lookup_expr='gte'
)
class Meta:
model = User
fields = ['username', 'is_active']
def filter_full_name(self, queryset, name, value):
return queryset.filter(
models.Q(first_name__icontains=value) |
models.Q(last_name__icontains=value)
)
class UserType(DjangoObjectType):
class Meta:
model = User
fields = '__all__'
filterset_class = UserFilterSet
class Query(graphene.ObjectType):
users = DjangoFilterConnectionField(UserType)class Post(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(User, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
published = models.BooleanField(default=False)
class PostType(DjangoObjectType):
class Meta:
model = Post
fields = '__all__'
filter_fields = {
'title': ['exact', 'icontains'],
'author': ['exact'],
'author__username': ['exact', 'icontains'],
'published': ['exact'],
'created_at': ['gte', 'lte']
}
# GraphQL query filtering by relationship:
# query {
# posts(author_Username_Icontains: "john", published: true) {
# edges {
# node {
# title
# author { username }
# }
# }
# }
# }from graphene_django.filter.filters import GlobalIDFilter
class PostFilterSet(FilterSet):
author_id = GlobalIDFilter(field_name='author')
class Meta:
model = Post
fields = ['title', 'published']
class PostType(DjangoObjectType):
class Meta:
model = Post
fields = '__all__'
filterset_class = PostFilterSet
# GraphQL query with global ID:
# query {
# posts(authorId: "VXNlclR5cGU6MQ==") {
# edges {
# node {
# title
# }
# }
# }
# }class Query(graphene.ObjectType):
my_posts = DjangoFilterConnectionField(PostType)
def resolve_my_posts(self, info, **args):
# Start with user's posts
queryset = Post.objects.filter(author=info.context.user)
# Apply django-filter filtering
filter_set = PostType._meta.filterset_class(
args,
queryset=queryset
)
return filter_set.qsfrom graphene_django.filter.filters import ArrayFilter
class TagFilterSet(FilterSet):
tags = ArrayFilter(field_name='tags__name', lookup_expr='contains')
class Meta:
model = Post
fields = ['title']
# For PostgreSQL ArrayField filtering:
# query {
# posts(tags: ["python", "django"]) {
# edges {
# node {
# title
# tags
# }
# }
# }
# }class UserFilterSet(FilterSet):
order_by = django_filters.OrderingFilter(
fields=(
('created_at', 'created'),
('username', 'username'),
('email', 'email'),
)
)
class Meta:
model = User
fields = ['is_active']
# GraphQL query with ordering:
# query {
# users(orderBy: "-created") {
# edges {
# node {
# username
# createdAt
# }
# }
# }
# }Install with Tessl CLI
npx tessl i tessl/pypi-graphene-django