Skip to content

Django REST Framework – Creating Views

Part 6 of 8 in the series Django REST Framework




Since our Models and Serializers are ready, we’ll now write our views. Also, unlike the Django REST Framework official tutorial which first explains regular Django views, then Function based views and last Class based views, We will directly write our view based on DRF’s Classes.

You can get all the files related to the examples here : https://github.com/hpin2019/coding-sessions/tree/master/drf-tutorial-1

QuoteList Class – Django REST Framework Views

from quotes.models import Quote
from quotes.serializers import QuoteSerializer
from django.http import Http404

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status


class QuoteList(APIView):
    '''
    List all quotes or create a new quote
    '''
    def get(self,request,format=None):
        print("Get quotes list called")
        quotes = Quote.objects.all()
        serializer = QuoteSerializer(quotes, many=True)
        return Response(serializer.data)


    def post(self, request, format=None):
        print("Create quote called")
        serializer = QuoteSerializer(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)
      

QuoteList class is based on APIView class and provides get method for getting the list of all quotes from db and post method for creating a new quote object in DB.

QuoteDetail Class – Django REST Framework Views

Let’s add another class for getting, updating and deleting one quote object.

class QuoteDetail(APIView):
    """
    Retrieve, update or delete a quote instance.
    """
    def get_object(self, pk):
        try:
            return Quote.objects.get(pk=pk)
        except Quote.DoesNotExist:
            raise Http404


    def get(self, request, pk, format=None):
        quote = self.get_object(pk)
        serializer = QuoteSerializer(quote)
        return Response(serializer.data)


    def put(self, request, pk, format=None):
        quote = self.get_object(pk)
        serializer = QuoteSerializer(quote, 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):
        quote = self.get_object(pk)
        quote.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

As you can see all the methods in this class takes pk (primary key) as input to work on particular quote object identified by id field in out quote db table.

That’s it. Our REST interface functions are ready. Now we need to expose these functions via Django’s URL routing.

URL Routing in Django

First create a urls.py file in our app’s folder : quotes.

(venv) $ vi quotes/urls.py 

And add following code.

from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from quotes import views

urlpatterns = [
    path('quotes/', views.QuoteList.as_view()),
    path('quotes/<int:pk>/', views.QuoteDetail.as_view()),
]

urlpatterns = format_suffix_patterns(urlpatterns)

As can be seen, quotes/ path is mapped to QuoteList view class’s methods and quotes/<int:pk>/ path is mapped to QuoteDetail view class’s methods.

So quotes/ path will only serve get and post methods and quotes/<int:pk>/ will only serve get, put and delete with pk as int input in path.

Now we need to add these paths to project’s urls.py file. so edit urls.py in project folder :

(venv) $ vi restapi/urls.py 

And add “api/” path as shown below :

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/',include('quotes.urls')),
]

So here we are telling Django that all the incoming calls to <server>/api/ path will be handled by routes defined in quotes.urls.

Now our models, serializers, views and url routing is ready. Let’s start the Django development server.

(venv) $ python  manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
February 17, 2020 - 15:29:14
Django version 3.0.2, using settings 'restapi.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Browseable APIs

Now, open any browser window and go to “http://127.0.0.1:8000/” and you’ll error like below :

Django REST framework Path error.

The reason being that our Django server can only serve the paths defined in urls.py.

Now try with : http://127.0.0.1:8000/api/quotes/ and you should be able to see :

Django REST Framework API View

Since there are no quotes in db, it’s returning empty list. Let’s add a quote by adding following json in the content section of the form provided below. Use below json format :

{
“text”: “You must be the CHANGE you wish to see in the WORLD”,
“author”: “Mahatma Gandhi”,
“image_url”: “None”
}

After adding, click POST button. After successful save, you can see that now our saved quote is being returned in the list.

Now, let’s check the Quote Detail APIs by going to url : http://127.0.0.1:8000/api/quotes/1/

Quote detail of quote id : 1

You can see that this is the REST API output of one particular quote as output have only one json object compared to our previous API output which had array/list of json objects.

Also, there is a DELETE button to delete this particular object and PUT button to modify this particular object.

Since our Basic CRUD (Create, Read, Update and Delete) APIs are now ready, next we will move to see how to customize browseable APIs.

Series Navigation<< DRF – DB Migrations and Serializers testingDRF – Browsable API >>
Published inDjango

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: