Function-Based API Views
In this page:
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.
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.
@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.
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. #}
- Forgetting the @api_view([GET, POST]) decorator, which leaves the view unable to parse JSON request bodies or render DRF's Response objects correctly.
- Returning a plain Django HttpResponse instead of DRF's Response, losing automatic content negotiation and the browsable API.
- Not checking request.method inside a view that handles multiple HTTP methods, causing GET logic to run even on a POST request.
- @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: