advanced class based views in Django Rest Framework


advanced class based views in Django Rest Framework

Django Rest Framework is super awesome to create an web API very quickly. It provides generic views to implement the common functionality. In the previous section we have discussed about class based views in Django REST. Django REST class based views allows us to create an api endpoint with a single request method type i.e one of "GET", "POST", "PUT", "PATCH", "DELETE", etc. But, advanced generic classbased views allows us to implement the more than a single request method.  It means we can implement more than a one functionality in a single api endpoint, like create and list, retrieve and update, retrieve destroy and retrieve, update and destroy.

Let's see advanced class based views in Django REST

  1. ListCreateAPIView
  2. RetrieveUpdateAPIView
  3. RetrieveDestroyAPIView
  4. RetrieveUpdateDestroyAPIView

Usage of  ListCreateAPIView in DRF:

  • It allows "GET", "POST" request methods only. "GET" request method is is to list all avilable model instances and "POST" request method is to create an instance in the model.
  • It is combination of "ListAPIView", "CreateAPIView".
  • It is recommended to use when you need both list and create functionalities in a single API endpoint.

Let's do some code to know how to implement it

# urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('movie-list-create/', views.MovieListCreateView.as_view(), name='movie_list_create'),
]

#views.py

from rest_framework.generics import ListCreateAPIView
from .serializers import *

class MovieListCreateView(ListCreateAPIView):
    queryset = Movie.objects.all()
    serializer_class = MovieSerializer

Now, send a "GET" request to the url "/movie-list-create/" (i.e it will be changed based on your url path) then you will see output something like below with HTTP Status code of 200.

[
    {
        "id": 1,
        "title": "Bahubali The Beginning",
        "released_on": "2015-07-10",
        "genre": "fiction",
        "director": "SS Rajamouli"
    }
]

Send a "POST" request to the same api endpoint or url  with below JSON data

{
        "title": "Bahubali The Conclusion",
        "released_on": "2017-04-28",
        "genre": "fiction",
        "director": "SS Rajamouli"
}

Now, we can see the ouput something like below with HTTP status code 201

{
    "id": 3,
    "title": "Bahubali The Conclusion",
    "released_on": "2017-04-28",
    "genre": "fiction",
    "director": "SS Rajamouli"
}

Usage of  RetrieveUpdateAPIView in DRF:

  • It allows "GET", "PUT" and "PATCH" request methods only.  "GET" request method is to retrieve the specific existing model instancec/resource. 

  • "PUT" and "PATCH" request methods are used to update the existing specific resource. If you want to complete update the existing model instance/resource then use "PUT" request method otherwise use "PATCH" request method.

  • "PATCH" request method is used to update some parts of the existing specific resource.
  • For all these request methods we need to send primary key equivalent url keyword argument in the the request so that server can uniquely identify the model instance/resource. The url keyword argument mostly sent as a part of the url.
  • It is recommended to use when you need both retrieve and update functionalities in a single API endpoint.

Let's do some code to know how to implement it

# urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('movie/<int:pk>/retrieve-update/', views.MovieRetrieveUpdateView.as_view(), name='movie_retrieve_update'),
]

# views.py

from rest_framework.generics import RetrieveUpdateAPIView
from .serializers import *
class MovieRetrieveUpdateView(RetrieveUpdateAPIView):
    queryset = Movie.objects.all()
    serializer_class = MovieSerializer

Now, we are ready to test our API. Send a "GET" request to url "/movie/3/retrieve-update/" then you will see output something like below with HTTP status code 200. Note: "3" is  primary key of object in the url if may be different for you.

{
    "id": 3,
    "title": "Bahubali The Conclusion",
    "released_on": "2017-04-28",
    "genre": "fiction",
    "director": "SS Rajamouli"
}

Let's test "PUT" request method to completely update the object/resource. To do that send "PUT" request to the same url with below JSON data.

{
        "title": "Bahubali The Conclusion Updates",
        "released_on": "2017-04-28",
        "genre": "fiction",
        "director": "SS Rajamouli"
}

Now, you can see output something like below with HTTP status code 200.

{
    "id": 3,
    "title": "Bahubali The Conclusion Updates",
    "released_on": "2017-04-28",
    "genre": "fiction",
    "director": "SS Rajamouli"
}

Let's do partial update to the same resourse by sending the "PATCH" request to it with below JSON data to the same url.

{
    "title": "Bahubali The Conclusion"
}

Now, you can see output something like below with HTTP status code 200.

{
    "id": 3,
    "title": "Bahubali The Conclusion",
    "released_on": "2017-04-28",
    "genre": "fiction",
    "director": "SS Rajamouli"
}

Usage of  RetrieveDestroyAPIView in DRF:

  • it allows "GET" and "DELTE" request methods only all other methods will result in HTTP status code of 405.

  • "GET" request method is to retrieve the existing specific model instancec/resource and "DELETE" request method is to destroy the existing specific model instance/resource.

  • In both these request types we need to send primary key equivalent url keyword argument in the request so that server can uniquely identify the model instance/resource. The url keyword argument mostly sent as a part of the url.
  • It is recommended to use when you need retrieve and delete functionalities in a single API endpoint.

Let's do some code to know how to use it.

# urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('movie//retrieve-destroy/', views.MovieRetrieveDestroyView.as_view(), name='movie_retrieve_destroy'),
]

# views.py

from rest_framework.generics import RetrieveDestroyAPIView
from .serializers import *

class MovieRetrieveDestroyView(RetrieveDestroyAPIView):
    queryset = Movie.objects.all()
    serializer_class = MovieSerializer

Now it's time to test the above code.

In "RetrieveUpdateAPIView" we have already seen how to send a GET request so you can simply use the same procedure to test it.

To delete the object/resource then send "DELETE" request to url "/movie/3/retrieve-destroy/" then it will response with status code 204 - No content. Now check the Movie with pk="3" (note: it may be different for you) in the database you will not find it. Because it was deleted in last request.

Usage of  RetrieveUpdateDestroyAPIView in DRF:

  • It allows 4 requests, "GET", "PUT", "PATCH" and "DELETE".
  • It is recommended to use when you need retrieve, update and delete functionalities in a single API endpoint.

Let's do some code to know how to use it.

# urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('movie//retrieve-destroy/', views.MovieRetrieveUpdateDestroyView.as_view(), name='movie_retrieve_update_destroy'),
]

# views.py

from rest_framework.generics import RetrieveUpdateDestroyAPIView
from .serializers import *

class MovieRetrieveUpdateDestroyView(RetrieveUpdateDestroyAPIView):
    queryset = Movie.objects.all()
    serializer_class = MovieSerializer

For testing you can use same procedures that I have mentioned for other api classes above.

Please let me know if you have any questions in the below comments. You can find all this code in my github repository (https://github.com/AnjaneyuluBatta505/learnbatta/tree/master/django-rest-framework/classbasedviews).

Support Me on Patreon