Run this checklist every time you build a DRF API view (APIView, ViewSet, or generic view).

Standard: Backend-First Logic Standard


1. View Type Decision

Use This When
APIView Custom logic that doesn't map cleanly to CRUD
generics.ListCreateAPIView Standard list + create endpoint
generics.RetrieveUpdateDestroyAPIView Standard get + update + delete endpoint
ModelViewSet Full CRUD with routing via router.register()
ReadOnlyModelViewSet List + retrieve only




2. Authentication & Permissions



— IsAuthenticated: logged-in users only

— IsAdminUser: admin-only

— Custom: e.g., IsWorkspaceMember, IsWorkspaceAdmin





3. Serializer



serializer_class = ProjectSerializer (read — includes nested data)

write_serializer_class = ProjectWriteSerializer (write — flat fields only)




4. Business Logic Placement

[ ] View calls a service function — it does NOT contain business logic itself

CORRECT:
  def post(self, request):
      serializer = ProjectWriteSerializer(data=request.data)
      serializer.is_valid(raise_exception=True)
      project = ProjectService.create_project(
          workspace_id=..., actor=request.user, **serializer.validated_data
      )
      return Response(ProjectSerializer(project).data, status=201)

WRONG — logic in the view:
  def post(self, request):
      project = Project.objects.create(...)
      TaskList.objects.create(project=project, ...)

[ ] No ORM calls in the view body (except .get() or .filter() for object retrieval)
[ ] No email sending, file handling, or external API calls in the view

5. Response Format


— 200 OK: GET (retrieve or list)

— 201 Created: POST (create)

— 200 OK: PATCH/PUT (update — or 204 No Content if no body)

— 204 No Content: DELETE


— 400 Bad Request: validation error

— 401 Unauthorized: authentication required

— 403 Forbidden: authenticated but no permission

— 404 Not Found: object does not exist

— 409 Conflict: duplicate / uniqueness conflict

— 500 Internal Server Error: unexpected (logged, generic message returned)



{ "error": "DUPLICATE", "message": "A project with this name already exists." }


6. Filtering, Sorting, Pagination









7. Error Handling








8. URL Configuration







9. Testing











Done When











Practice Task

DRF API View Task Build a ProjectListCreateView and ProjectDetailView with authentication, permission checks, service delegation, and pagination.