Django Rest Framework CRUD Methods in One View: GET, POST, PUT, and DELETE

Django Rest Framework (DRF) has become a popular choice for building robust and flexible APIs in Django applications. It provides a wide range of tools and features to streamline the development process. One such feature is the ability to combine multiple HTTP methods (GET, POST, PUT, DELETE) into a single view, enhancing the efficiency of your API. In this blog, we will explore how to create a single view that handles all these HTTP methods using Django Rest Framework.

Why Combine Multiple Methods?

Traditionally, when building APIs, developers create separate views for each HTTP method (GET, POST, PUT, DELETE) to handle various actions on a resource. This approach can lead to code duplication and increased complexity, making it harder to maintain and understand the API as it grows. By combining these methods into a single view, we can promote code reusability, reduce boilerplate code, and improve overall API readability.

Prerequisites:

Before we begin, ensure you have the following prerequisites in place:

  1. Django installed on your system.
  2. Basic familiarity with Django project structure and database concepts.
  3. Virtual Environment, this is optional but recommended. You check our blog here.

Note: For this tutorial, we are using our basic skeleton project for Django. You can also download the project from here.

All in One API Method in One View Example using APIView

Step 1: Create the Django Model

First, define the Django model that represents a book. In your app’s models.py, add the following code:

from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=100)
    publication_date = models.DateField()

Don’t forget to run python manage.py makemigrations and python manage.py migrate to create the corresponding database table for the model.

Step 2: Create the Serializer

Next, create a serializer to convert the book model instances into JSON data and vice versa. In your app’s serializers.py, add the following code:

from rest_framework import serializers
from .models import Book

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ['__all__']

Learn More on How to Serializer and Deserializer in Django Rest Framework with Examples

Step 3: Combining All in One Methods in the View

Now, let’s create a single view in views.py that handles all the HTTP methods for the ‘Book’ model.

class BookView(APIView):
    def get(self, request, pk=None):  # Add 'pk=None' to the get method
        if pk is not None:
            book = Book.objects.get(pk=pk)
            serializer = BookSerializer(book)
            return Response(serializer.data)
        else:
            books = Book.objects.all()
            serializer = BookSerializer(books, many=True)
            return Response(serializer.data)

    def post(self, request):
        serializer = BookSerializer(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)

    def put(self, request, pk=None):  # Add 'pk=None' to the put method
        if pk is not None:
            book = Book.objects.get(pk=pk)
            serializer = BookSerializer(book, data=request.data)
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response({'error': 'Please provide a valid book ID.'}, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk=None):  # Add 'pk=None' to the delete method
        if pk is not None:
            book = Book.objects.get(pk=pk)
            book.delete()
            return Response(status=status.HTTP_204_NO_CONTENT)
        else:
            books = Book.objects.all()
            books.delete()
            return Response(status=status.HTTP_204_NO_CONTENT)

Step 4: Define the URL Pattern

Finally, wire up the URL patterns to the newly created view in the urls.py file.

from django.urls import path
from .views import BookView

urlpatterns = [
    path('api/books/', BookView.as_view(), name='book-list'),
    path('api/book/<int:pk>/', BookView.as_view(), name='book-detail'),
]

Step 3: Test the API’s

With the API set up, test the method to for different requests on book. Utilize tools like curl or Postman to send request to the URL’s.

Below are some example cURL commands for making HTTP requests to the Django REST Framework API we’ve discussed earlier:

  1. Making a GET request to retrieve all books:
curl -X GET http://localhost:8000/api/books/
  1. Making a GET request to retrieve a specific book with a given ID (e.g., 1):
curl -X GET http://localhost:8000/api/book/1/
  1. Making a POST request to create a new book:
curl -X POST -H "Content-Type: application/json" -d '{"title":"Sample Book","author":"John Doe","publication_date":"2023-07-30"}' http://localhost:8000/api/books/
  1. Making a PUT request to update an existing book with ID 1:
curl -X PUT -H "Content-Type: application/json" -d '{"title":"Updated Book","author":"Jane Doe","publication_date":"2023-08-15"}' http://localhost:8000/api/book/1/
  1. Making a DELETE request to remove an existing book with ID 1:
curl -X DELETE http://localhost:8000/api/book/1/
  1. Making a DELETE request to remove all books:
curl -X DELETE http://localhost:8000/api/books/

Remember to replace http://localhost:8000/ with the actual URL of your API. Additionally, ensure that the cURL command is executed in your terminal or command prompt. These commands will allow you to interact with the Django REST Framework API and perform CRUD (Create, Read, Update, Delete) operations on the ‘Task’ resource.

Conclusion

In this blog, we explored how to combeine the GET, POST, PUT, and DELETE methods into a single view in Django Rest Framework. By doing so, we can create a more efficient, maintainable, and readable API. This approach is particularly useful for small to medium-sized projects where simplicity and code reuse are essential. However, for more complex projects, it is recommended to use separate views for better organization and scalability.

Find this tutorial on Github.

Blogs You Might Like to Read!