CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-djangorestframework-jsonapi

A Django REST framework API adapter for the JSON:API spec.

Pending
Overview
Eval results
Files

views.mddocs/

Views

Enhanced Django REST framework views with JSON:API features including automatic include parameter handling, relationship views, prefetching optimization, and JSON:API response formatting.

Capabilities

ModelViewSet

Enhanced ModelViewSet with JSON:API features and automatic optimization.

class ModelViewSet(PreloadIncludesMixin, viewsets.ModelViewSet):
    """
    JSON:API compatible ModelViewSet with automatic include handling and optimization.
    
    Inherits all Django REST framework ModelViewSet functionality while adding:
    - Automatic prefetching based on include parameter
    - JSON:API response formatting
    - Relationship endpoint support
    - Resource type detection
    """
    
    queryset = None           # QuerySet for this viewset
    serializer_class = None   # Serializer class
    resource_name = None      # Override resource type name
    
    # Optimization configuration
    prefetch_for_includes = {}  # Prefetch config for include paths
    select_for_includes = {}    # Select_related config for include paths

Usage example:

from rest_framework_json_api import views
from myapp.models import Article
from myapp.serializers import ArticleSerializer

class ArticleViewSet(views.ModelViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    
    # Optimize queries for common includes
    prefetch_for_includes = {
        '__all__': [],  # Always prefetch these
        'author': ['author'],
        'comments': ['comments'],
        'comments.user': ['comments__user']
    }
    
    select_for_includes = {
        'author': ['author'],
        'category': ['category']
    }

# Automatically handles: GET /articles?include=author,comments
# And optimizes database queries accordingly

ReadOnlyModelViewSet

Read-only version of ModelViewSet for read-only API endpoints.

class ReadOnlyModelViewSet(PreloadIncludesMixin, viewsets.ReadOnlyModelViewSet):
    """
    JSON:API compatible ReadOnlyModelViewSet.
    
    Provides list and retrieve actions only with JSON:API features:
    - Include parameter support
    - Automatic query optimization
    - JSON:API response formatting
    """
    
    queryset = None
    serializer_class = None
    resource_name = None

RelationshipView

Specialized view for JSON:API relationship endpoints.

class RelationshipView(generics.GenericAPIView):
    """
    View for JSON:API relationship endpoints.
    
    Handles relationship manipulation endpoints like:
    - GET /articles/1/relationships/author
    - POST /articles/1/relationships/tags  
    - PATCH /articles/1/relationships/author
    - DELETE /articles/1/relationships/tags
    """
    
    queryset = None
    serializer_class = None
    related_field = None      # Name of the related field
    
    def get(self, request, *args, **kwargs):
        """Get relationship data."""
    
    def post(self, request, *args, **kwargs):
        """Add to relationship (for to-many relationships)."""
    
    def patch(self, request, *args, **kwargs): 
        """Replace relationship data."""
    
    def delete(self, request, *args, **kwargs):
        """Remove from relationship (for to-many relationships)."""

Usage example:

from django.urls import path
from rest_framework_json_api.views import RelationshipView

class ArticleAuthorRelationshipView(RelationshipView):
    queryset = Article.objects.all()
    related_field = 'author'

# In urls.py:
urlpatterns = [
    path('articles/<int:pk>/relationships/author/', 
         ArticleAuthorRelationshipView.as_view()),
]

RelatedMixin

Base mixin that provides related field handling functionality.

class RelatedMixin:
    """
    Base mixin for handling related field operations in JSON:API views.
    
    Provides utilities for getting related instances and handling
    relationship operations.
    """
    
    def get_related_instance(self):
        """Get related instance for relationship operations."""
    
    def get_relation_instance(self, resource_instance, source, serializer):
        """Get specific relation instance from resource."""

PreloadIncludesMixin

Mixin that provides automatic query optimization based on include parameters.

class PreloadIncludesMixin:
    """
    Mixin for automatic query optimization based on include parameter.
    
    Configuration attributes:
    - prefetch_for_includes: Dict mapping include paths to prefetch_related() args
    - select_for_includes: Dict mapping include paths to select_related() args
    
    Special key '__all__' applies to all requests regardless of include parameter.
    """
    
    prefetch_for_includes = {}  # Include path -> prefetch list mapping
    select_for_includes = {}    # Include path -> select_related list mapping
    
    def get_select_related(self, include):
        """
        Get select_related args for an include path.
        
        Args:
            include: Include path string (e.g., 'author', 'comments.user')
            
        Returns:
            list or None: Arguments for select_related()
        """
    
    def get_prefetch_related(self, include):
        """
        Get prefetch_related args for an include path.
        
        Args:
            include: Include path string
            
        Returns:
            list or None: Arguments for prefetch_related()
        """
    
    def get_queryset(self, *args, **kwargs):
        """
        Enhanced get_queryset with automatic optimization.
        
        Analyzes include parameter and applies appropriate
        select_related and prefetch_related optimizations.
        """

Usage example:

class ArticleViewSet(PreloadIncludesMixin, viewsets.ModelViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    
    # When ?include=author is requested, select_related('author')
    select_for_includes = {
        'author': ['author'],
        'category': ['category'],
        'author.profile': ['author__profile']
    }
    
    # When ?include=comments is requested, prefetch_related('comments')
    prefetch_for_includes = {
        'comments': ['comments'],
        'tags': ['tags'],
        'comments.user': ['comments__user']
    }

AutoPrefetchMixin

Mixin that automatically detects and prefetches relationships.

class AutoPrefetchMixin:
    """
    Mixin for automatic prefetching of OneToOne and ManyToMany relationships.
    
    Automatically analyzes include parameter and applies appropriate
    prefetching for detected relationship types without manual configuration.
    """
    
    def get_queryset(self, *args, **kwargs):
        """
        Enhanced get_queryset with automatic relationship detection.
        
        Automatically detects relationship types and applies:
        - select_related for ForeignKey and OneToOne
        - prefetch_related for ManyToMany and reverse ForeignKey
        """

Include Parameter Support

Views automatically handle the JSON:API include parameter:

# GET /articles?include=author,comments,tags
# Automatically includes related resources in response:
{
  "data": [{
    "type": "articles",
    "id": "1",
    "relationships": {
      "author": {"data": {"type": "authors", "id": "5"}},
      "comments": {"data": [{"type": "comments", "id": "10"}]},
      "tags": {"data": [{"type": "tags", "id": "2"}]}
    }
  }],
  "included": [
    {"type": "authors", "id": "5", "attributes": {...}},
    {"type": "comments", "id": "10", "attributes": {...}},
    {"type": "tags", "id": "2", "attributes": {...}}
  ]
}

Query Optimization

Views provide sophisticated query optimization:

class ArticleViewSet(views.ModelViewSet):
    queryset = Article.objects.all()
    
    # Manual optimization configuration
    prefetch_for_includes = {
        '__all__': ['tags'],  # Always prefetch tags
        'author': ['author'],
        'comments': ['comments'],
        'comments.user': ['comments__user'],
        'category.section': ['category']  # Nested relationships
    }
    
    select_for_includes = {
        'author': ['author', 'author__profile'],
        'category': ['category'],
        'category.parent': ['category__parent']
    }

# Or use AutoPrefetchMixin for automatic detection:
class ArticleViewSet(AutoPrefetchMixin, views.ModelViewSet):
    queryset = Article.objects.all()
    # No manual configuration needed

Resource Name Customization

Views support custom resource names:

class ArticleViewSet(views.ModelViewSet):
    queryset = Article.objects.all()
    resource_name = 'blog-posts'  # Override default 'articles'

# Results in resource type 'blog-posts' instead of 'articles'

Error Handling

Views integrate with JSON:API error formatting:

# 404 errors become:
{
  "errors": [{
    "status": "404",
    "detail": "Not found."
  }]
}

# Validation errors become:
{
  "errors": [{
    "status": "400", 
    "detail": "This field is required.",
    "source": {"pointer": "/data/attributes/title"}
  }]
}

Types

from rest_framework_json_api.views import (
    ModelViewSet,
    ReadOnlyModelViewSet,
    RelationshipView,
    PreloadIncludesMixin,
    AutoPrefetchMixin
)

# Base classes from Django REST framework
from rest_framework import viewsets, generics

Install with Tessl CLI

npx tessl i tessl/pypi-djangorestframework-jsonapi

docs

exceptions-utilities.md

filtering.md

index.md

pagination.md

relations.md

renderers-parsers.md

serializers.md

views.md

tile.json