Skip to content

hamedasgari20/Django-Rest-Framework-Views

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 

Repository files navigation

Django Rest Framework Views

Django Rest Framework Views

APIView class is a base for all the views that you might choose to use in your DRF application.

  • Extending APIView offers the most freedom, but it also leaves a lot more work for you. It's a great choice if you need to have control over every aspect of the view or if you have very complicated views.
  • With the generic view classes, you can develop faster and still have quite a bit of control over the API endpoints.
  • With ModelViewSets, you can get an API stood up with five lines of codes

To quickly see the differences between them, let's look at example of all three in action achieving the same thing.

In the following we wants to do the below actions by different views:

  • Listing all items
  • Creating a new item
  • Retrieving, updating, and deleting a single item

APIViews

Read more in DRF documentation part 1

Read more in DRF documentation part 2

Here's how you can accomplish this by extending APIView:

class ItemsList(APIView):

    def get(self, request, format=None):
        items = Item.objects.all()
        serializer = ItemSerializer(items, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = ItemSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class ItemDetail(APIView):

    def get(self, request, pk, format=None):
        item = get_object_or_404(Item.objects.all(), pk=pk)
        serializer = ItemSerializer(item)

        return Response(serializer.data)

    def put(self, request, pk, format=None):
        item = get_object_or_404(Item.objects.all(), pk=pk)
        serializer = ItemSerializer(item, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk, format=None):
        item = get_object_or_404(Item.objects.all(), pk=pk)
        item.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

Its url.pyfile:

from django.urls import path
from views import ItemsList, ItemDetail

urlpatterns = [
    path('api-view', ItemsList.as_view()),
    path('api-view/<pk>', ItemDetail.as_view()),
]

Class-based Views

Here's a Class-based View that allows users to delete all the items at once:

from rest_framework.permissions import IsAuthenticated
from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response
from rest_framework.views import APIView

class ItemsNotDone(APIView):

    permission_classes = [IsAuthenticated]  # policy attribute
    renderer_classes = [JSONRenderer]       # policy attribute

    def get(self, request):

        user_count = Item.objects.filter(done=False).count()
        content = {'not_done': user_count}

        return Response(content)

Function-based Views

If you're writing a view in the form of a function, you'll need to use the @api_view decorator.

from rest_framework.decorators import api_view, permission_classes, renderer_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response

@api_view(['GET'])
@permission_classes([IsAuthenticated])  # policy decorator
@renderer_classes([JSONRenderer])       # policy decorator
def items_not_done(request):
    user_count = Item.objects.filter(done=False).count()
    content = {'not_done': user_count}

    return Response(content)

Generic Views

Read more in DRF documentation part 1

Read more in DRF documentation part 2

Here's how you do the same thing with concrete generic views:

class ItemsListGeneric(ListCreateAPIView):
    queryset = Item.objects.all()
    serializer_class = ItemSerializer


class ItemDetailGeneric(RetrieveUpdateDestroyAPIView):
    queryset = Item.objects.all()
    serializer_class = ItemSerializer

Its url.pyfile:

from django.urls import path,
from views import ItemsListGeneric, ItemDetailGeneric

urlpatterns = [
    path('generic-view', ItemsListGeneric.as_view()),
    path('generic-view/<pk>', ItemDetailGeneric.as_view()),
]

ViewSets

ViewSet classes remove the need for additional lines of code and, when coupled with routers, help keep your URLs consistent. The most significant advantage of ViewSets is that the URL construction is handled automatically (with a router class).

Read more in DRF documentation part 1

Read more in DRF documentation part 2

And here are the lines that you need with ModelViewSet:

class ItemsViewSet(ModelViewSet):
    serializer_class = ItemSerializer
    queryset = Item.objects.all()

Its url.pyfile:

from django.urls import path, include
from rest_framework import routers
from views import ItemsViewSet

router = routers.DefaultRouter()
router.register(r'viewset', ItemsViewSet)

urlpatterns = [
    path('', include(router.urls)),
]

There are four types of ViewSets, from the most basic to the most powerful:

1- ViewSet

2- GenericViewSet

3- ReadOnlyModelViewSet

4- ModelViewSet

NOTE: This article is under development and will be improved ...

About

Django Rest Framework Views

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published