Skip to content

Types

Graphene-Django-Extras provides enhanced type classes that extend the basic graphene-django functionality.

DjangoListObjectType

Recommended for Types

Extends DjangoObjectType with built-in pagination and filtering support.

from graphene_django_extras import DjangoListObjectType
from graphene_django_extras.paginations import LimitOffsetGraphqlPagination
from django.contrib.auth.models import User

class UserListType(DjangoListObjectType):
    class Meta:
        description = "Type definition for user list"
        model = User
        pagination = LimitOffsetGraphqlPagination(
            default_limit=25, 
            ordering="-date_joined"
        )
        filter_fields = {
            "username": ("exact", "icontains"),
            "email": ("exact", "icontains"),
            "is_active": ("exact",),
        }

Features

  • Built-in Pagination: Automatic pagination with configurable settings
  • Filtering: Integrated django-filter support
  • Ordering: Custom ordering options
  • Caching: Optional query result caching
  • Custom Queryset: Override default queryset behavior

Configuration Options

class UserListType(DjangoListObjectType):
    class Meta:
        model = User
        description = "User list with advanced features"

        # Pagination
        pagination = LimitOffsetGraphqlPagination(
            default_limit=20,
            max_limit=100,
            ordering=("-date_joined", "username")
        )

        # Filtering
        filter_fields = {
            "username": ("exact", "icontains", "istartswith"),
            "email": ("exact", "icontains"),
            "date_joined": ("exact", "gte", "lte"),
            "is_active": ("exact",),
            "groups": ("exact",),
        }

        # Custom queryset
        queryset = User.objects.select_related('profile')

        # Field restrictions
        fields = ("id", "username", "email", "first_name", "last_name")
        exclude = ("password",)

Helper Methods

class Query(graphene.ObjectType):
    # Get both list and retrieve fields
    users = UserListType.ListField(description="List all users")
    user = UserListType.RetrieveField(description="Get single user")

DjangoInputObjectType

Creates input types for mutations based on Django models.

from graphene_django_extras import DjangoInputObjectType
from django.contrib.auth.models import User

class UserInput(DjangoInputObjectType):
    class Meta:
        description = "User input for mutations"
        model = User
        fields = ("username", "email", "first_name", "last_name")
        # or exclude specific fields
        # exclude = ("password", "date_joined", "last_login")

Advanced Configuration

import graphene
from graphene_django_extras import DjangoInputObjectType

class UserCreateInput(DjangoInputObjectType):
    """Input for creating new users"""

    # Add custom fields
    confirm_password = graphene.String(required=True)

    class Meta:
        model = User
        fields = ("username", "email", "first_name", "last_name", "password")
        description = "Input type for user creation"

class UserUpdateInput(DjangoInputObjectType):
    """Input for updating existing users"""

    class Meta:
        model = User
        fields = ("email", "first_name", "last_name")
        description = "Input type for user updates"

Usage in Mutations

class CreateUserMutation(graphene.Mutation):
    class Arguments:
        input = UserCreateInput(required=True)

    user = graphene.Field(UserType)
    success = graphene.Boolean()

    def mutate(self, info, input):
        # Access input fields
        username = input.username
        email = input.email
        # ... mutation logic

DjangoSerializerType

Recommended for Quick Setup

Automatically generates types, queries, and mutations based on DRF serializers.

from graphene_django_extras import DjangoSerializerType
from graphene_django_extras.paginations import LimitOffsetGraphqlPagination
from .serializers import UserSerializer

class UserModelType(DjangoSerializerType):
    class Meta:
        description = "User model type with auto-generated operations"
        serializer_class = UserSerializer
        pagination = LimitOffsetGraphqlPagination(
            default_limit=25, 
            ordering="-date_joined"
        )
        filter_fields = {
            "username": ("exact", "icontains"),
            "email": ("exact", "icontains"),
            "is_active": ("exact",),
        }

Auto-generated Query Fields

class Query(graphene.ObjectType):
    # Generate both retrieve and list queries automatically
    user_retrieve, user_list = UserModelType.QueryFields(
        description='User queries',
        deprecation_reason='Optional deprecation message'
    )

    # Or define them separately
    user_detail = UserModelType.RetrieveField(
        description='Get single user by ID'
    )
    user_list_custom = UserModelType.ListField(
        description='List users with filtering and pagination'
    )

Auto-generated Mutation Fields

class Mutation(graphene.ObjectType):
    # Generate all CRUD mutations
    user_create, user_delete, user_update = UserModelType.MutationFields(
        description='User CRUD operations'
    )

    # Or define them separately
    create_user = UserModelType.CreateField(description='Create new user')
    delete_user = UserModelType.DeleteField(description='Delete user')
    update_user = UserModelType.UpdateField(description='Update user')

Serializer Integration

# serializers.py
from rest_framework import serializers
from django.contrib.auth.models import User

class UserSerializer(serializers.ModelSerializer):
    full_name = serializers.SerializerMethodField()

    class Meta:
        model = User
        fields = ['id', 'username', 'email', 'first_name', 'last_name', 'full_name']

    def get_full_name(self, obj):
        return f"{obj.first_name} {obj.last_name}".strip()

# The DjangoSerializerType will automatically use these fields
class UserModelType(DjangoSerializerType):
    class Meta:
        serializer_class = UserSerializer

Type Comparison

Feature DjangoListObjectType DjangoInputObjectType DjangoSerializerType
Purpose List queries with pagination Input for mutations Complete CRUD operations
Pagination ✅ Built-in ❌ N/A ✅ Built-in
Filtering ✅ Built-in ❌ N/A ✅ Built-in
Auto Queries Manual setup ❌ N/A ✅ Auto-generated
Auto Mutations ❌ No ❌ N/A ✅ Auto-generated
Serializer Integration ❌ No ❌ No ✅ Full integration
Customization High High Medium
Setup Complexity Medium Low Low

Best Practices

1. Choose the Right Type

# ✅ For list queries with custom logic
class UserListType(DjangoListObjectType):
    class Meta:
        model = User

# ✅ For input validation
class UserInput(DjangoInputObjectType):
    class Meta:
        model = User
        fields = ("username", "email")

# ✅ For rapid prototyping
class UserModelType(DjangoSerializerType):
    class Meta:
        serializer_class = UserSerializer

2. Use Descriptive Names

# ✅ Clear naming
class UserListType(DjangoListObjectType): pass
class CreateUserInput(DjangoInputObjectType): pass
class UserCRUDType(DjangoSerializerType): pass

# ❌ Confusing naming
class UserType(DjangoListObjectType): pass  # Is it single or list?
class UserInput(DjangoSerializerType): pass  # Not an input type

3. Optimize Performance

class UserListType(DjangoListObjectType):
    class Meta:
        model = User
        # Optimize database queries
        queryset = User.objects.select_related('profile').prefetch_related('groups')

        # Limit exposed fields
        fields = ("id", "username", "email", "first_name", "last_name")

        # Enable caching for expensive queries
        # (Configure in settings)

4. Combine Types Strategically

# Use DjangoSerializerType for basic CRUD
class UserModelType(DjangoSerializerType):
    class Meta:
        serializer_class = UserSerializer

# Use DjangoListObjectType for complex list logic
class UserAnalyticsType(DjangoListObjectType):
    total_posts = graphene.Int()

    class Meta:
        model = User

    def resolve_total_posts(self, info):
        return self.posts.count()

# Use DjangoInputObjectType for complex input validation
class UserRegistrationInput(DjangoInputObjectType):
    confirm_password = graphene.String(required=True)
    terms_accepted = graphene.Boolean(required=True)

    class Meta:
        model = User
        fields = ("username", "email", "password")