Django REST Framework (DRF)

4 interview angles 3 min read source

Django REST Framework (DRF)

DRF is a toolkit built on top of Django for building HTTP APIs. It does not replace Django — it sits on the URL/view layer and adds: serializers (validation + (de)serialization), class-based API views, viewsets, routers, content negotiation, auth/permission/throttle classes, pagination, filtering, browsable API.

What DRF gives you on top of Django

Concern Plain Django DRF
(De)serialization Manual model_to_dict / JsonResponse Serializer, ModelSerializer with validation
View base View, TemplateView APIView, GenericAPIView, ViewSet, ModelViewSet
URL wiring path(...) per view Router auto-registers CRUD + @action endpoints
Auth Sessions, decorators authentication_classes (Session, Token, JWT, custom)
Permissions @login_required, @permission_required permission_classes per view/action, object-level perms
Negotiation Single response type Renderer/parser classes choose JSON/HTML/etc. by Accept
Browsable API None Self-documenting HTML UI in dev
Pagination Manual Paginator Pluggable pagination_class (Page/Limit/Cursor)
Filtering Manual request.GET filter_backends + django-filter

Minimal end-to-end example

# models.py
class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey("Author", on_delete=models.CASCADE, related_name="books")

# serializers.py
from rest_framework import serializers
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ["id", "title", "author"]

# views.py
from rest_framework import viewsets
class BookViewSet(viewsets.ModelViewSet):
    queryset = Book.objects.select_related("author")
    serializer_class = BookSerializer

# urls.py
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register("books", BookViewSet)
urlpatterns = [path("api/", include(router.urls))]

That single ViewSet wires up: GET /api/books/, POST /api/books/, GET/PUT/PATCH/DELETE /api/books/{pk}/.

Request lifecycle (what happens for every API call)

  1. URL resolver finds the view (router-generated or manual).
  2. APIView.dispatch() wraps Django’s HttpRequest into DRF’s Request.
  3. perform_authentication() runs each authentication_classes until one returns a user (or all return NoneAnonymousUser).
  4. check_permissions() runs permission_classes. Failure → 403/401.
  5. check_throttles() runs throttle_classes. Failure → 429.
  6. Method handler (get/post/…) runs. Body is parsed by parser_classes.
  7. Returned Response is rendered by the negotiated renderer_classes based on Accept.

Memorize this — it’s the spine of “why isn’t my permission/auth running” debugging.

File layout in this folder

# File Topic
02 02_serializers.md Serializer vs ModelSerializer, fields, to_representation
03 03_validation.md field-level, object-level, validators, UniqueTogether
04 04_views_apiview_viewsets.md APIViewGenericAPIViewViewSet ladder
05 05_routers_actions.md Routers, @action, basenames
06 06_permissions.md IsAuthenticated, custom, object-level
07 07_authentication.md Session/Token/JWT, custom auth class
08 08_throttling.md Anon/User/Scoped throttles
09 09_pagination.md PageNumber, LimitOffset, Cursor
10 10_filtering_searching.md SearchFilter, OrderingFilter, django-filter
11 11_nested_writable_serializers.md Writable nested create()/update()
12 12_performance_n_plus_1.md select_related/prefetch_related traps
13 13_testing.md APIClient, force_authenticate
14 14_exception_handling.md exception_handler, custom errors
15 15_versioning.md URL/header/namespace versioning
16 16_schema_openapi.md drf-spectacular, schema generation

Cross-links to related notes:

Interview angle

  • “Why DRF and not just Django views returning JsonResponse?” — auto CRUD via routers/viewsets, declarative validation via serializers, pluggable auth/perm/throttle stack, browsable API for onboarding, content negotiation.
  • “Walk me through what happens when a request hits a DRF endpoint.” — the 7-step lifecycle above.
  • “What’s the difference between Request and Django’s HttpRequest?” — DRF wraps it. request.data is parsed body (JSON/form/multipart unified), request.query_params aliases GET, and request.user/request.auth come from authentication_classes.
  • “Where does DRF hurt at scale?” — serializer overhead on huge querysets, hidden N+1 from SerializerMethodField, default ModelSerializer doing extra UNIQUE validator queries on writes. See 12_performance_n_plus_1.md.