← Back to Django Course | Chapter 14: REST API with DRF | Lesson 4 of 6

Function-Based API Views

The @api_view decorator turns a normal Django function into one that speaks JSON in and JSON out.

Writing a GET Endpoint

@api_view([GET]) marks this function as a DRF view. The view builds a queryset, serializes it, and returns the result wrapped in a DRF Response.

Example: Writing a GET Endpoint

@api_view([GET]) marks this function as a DRF view. The view builds a queryset, serializes it, and returns the result wrapped in a DRF Response.

markup
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import Book
from .serializers import BookSerializer

@api_view(['GET'])
def book_list(request):
    books = Book.objects.all()
    serializer = BookSerializer(books, many=True)
    return Response(serializer.data)
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}

Handling POST Requests

Allowing POST in @api_view lets this same function accept new data. request.data (not request.POST) holds the parsed JSON body in DRF views.

Example: Handling POST Requests

Allowing POST in @api_view lets this same function accept new data. request.data (not request.POST) holds the parsed JSON body in DRF views.

markup
@api_view(['GET', 'POST'])
def book_list(request):
    if request.method == 'POST':
        serializer = BookSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=201)
        return Response(serializer.errors, status=400)
    books = Book.objects.all()
    return Response(BookSerializer(books, many=True).data)
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}

Wiring Up the URL

A function-based API view is connected in urls.py exactly like a regular Django view.

Example: Wiring Up the URL

A function-based API view is connected in urls.py exactly like a regular Django view.

markup
from django.urls import path
from . import views

urlpatterns = [
    path('api/books/', views.book_list, name='book-list'),
]
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}
Common Mistakes
  1. Forgetting the @api_view([GET, POST]) decorator, which leaves the view unable to parse JSON request bodies or render DRF's Response objects correctly.
  2. Returning a plain Django HttpResponse instead of DRF's Response, losing automatic content negotiation and the browsable API.
  3. Not checking request.method inside a view that handles multiple HTTP methods, causing GET logic to run even on a POST request.
Chapter Summary
  • @api_view([GET, POST]) marks a function as a DRF API view and restricts which HTTP methods it accepts.
  • DRF's Response class replaces HttpResponse and automatically renders JSON (or the browsable API in a browser).
  • Function-based API views branch on request.method just like regular Django views.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.