Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Implementing Views and Renderers in Django REST Framework

Tech May 17 3

Django REST Framework (DRF) provides a powerful set of tools for building APIs. Among the most important components are Views, which handle request logic, and Renderers, which manage the output format. This guide explores the progression from low-level APIView to the high-level ModelViewSet, as well as how to control data presentation using Renderers.

Data Preparation

Before implementing views, we need a serializer to convert model instances into JSON data. Below is a standard ModelSerializer for a Role model.

from rest_framework import serializers
from .models import Role

class RoleModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Role
        fields = "__all__"

Working with APIView

The APIView class is the most basic view provided by DRF. When using it, you are responsible for handling pagination and serialization logic manually within the request methods.

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination
from .models import Role
from .serializers import RoleModelSerializer

class RolePagination(PageNumberPagination):
    page_size = 5
    page_size_query_param = 'size'
    max_page_size = 20

class RoleListAPIView(APIView):
    def get(self, request, *args, **kwargs):
        # Retrieve data from database
        queryset = Role.objects.all()
        
        # Initialize pagination
        paginator = RolePagination()
        paginated_queryset = paginator.paginate_queryset(queryset, request, view=self)
        
        # Serialize the paginated result
        serializer = RoleModelSerializer(instance=paginated_queryset, many=True)
        
        # Return paginated response structure
        return paginator.get_paginated_response(serializer.data)

To access this view, define a route in urls.py:

from django.urls import path
from .views import RoleListAPIView

urlpatterns = [
    path('roles/', RoleListAPIView.as_view()),
]

Streamlining Logic with GenericAPIView

GenericAPIView extends APIView by providing commonly used attributes like queryset and serializer_class. This reduces boilerplate code by offering helper methods like get_queryset() and get_serializer().

from rest_framework.generics import GenericAPIView

class RoleGenericListView(GenericAPIView):
    queryset = Role.objects.all()
    serializer_class = RoleModelSerializer
    pagination_class = RolePagination

    def get(self, request, *args, **kwargs):
        roles = self.get_queryset()
        page = self.paginate_queryset(roles)
        
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(roles, many=True)
        return Response(serializer.data)

Utilizing GenericViewSet

The GenericViewSet combines GenericAPIView logic with the flexibility of ViewSets. Instead of defining get or post methods, you define actions like list or create. The mapping between HTTP methods and actions is handled in the URL configuration.

from rest_framework.viewsets import GenericViewSet

class RoleViewSet(GenericViewSet):
    queryset = Role.objects.all()
    serializer_class = RoleModelSerializer
    pagination_class = RolePagination

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        page = self.paginate_queryset(queryset)
        serializer = self.get_serializer(page, many=True)
        return self.get_paginated_response(serializer.data)

In urls.py, you must specify the method mapping:

urlpatterns = [
    path('roles/', RoleViewSet.as_view({'get': 'list'})),
]

Efficiency with ModelViewSet

ModelViewSet is the most automated way to create a CRUD interface. It inherits from multiple mixins (List, Create, Retrieve, Update, Destroy), meening you often don't need to write any method logic at all.

from rest_framework.viewsets import ModelViewSet

class RoleFullViewSet(ModelViewSet):
    queryset = Role.objects.all()
    serializer_class = RoleModelSerializer
    pagination_class = RolePagination

The routing for ModelViewSet can handle both collection and instance endpoints:

urlpatterns = [
    path('roles/', RoleFullViewSet.as_view({'get': 'list', 'post': 'create'})),
    path('roles/<int:pk>/', RoleFullViewSet.as_view({
        'get': 'retrieve',
        'put': 'update',
        'patch': 'partial_update',
        'delete': 'destroy'
    })),
]

Controlling Output with Renderers

Renderers determine how the data is displayed to the client (e.g., as JSON or via a web-based UI). You can configure renderers globally or at the view level.

Global Configuration

In settings.py, you can define the default renderers for the entire project:

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ]
}

Local Configuration

To restrict a specific view to only one format, such as JSON, use the renderer_classes attribute:

from rest_framework.renderers import JSONRenderer

class SecureRoleView(APIView):
    renderer_classes = [JSONRenderer]
    
    def get(self, request):
        data = {"message": "This is only available as JSON"}
        return Response(data)

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.