Bird
Raised Fist0
Djangoframework~10 mins

ViewSets and routers in Django - Step-by-Step Execution

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Concept Flow - ViewSets and routers
Client sends HTTP request
Router matches URL to ViewSet
ViewSet selects action based on HTTP method
ViewSet calls appropriate method (list, create, retrieve, update, destroy)
ViewSet returns HTTP response
Client receives response
The router receives the request URL and directs it to the ViewSet, which picks the right method based on HTTP method and returns the response.
Execution Sample
Django
from rest_framework import viewsets, routers
from rest_framework.response import Response

class BookViewSet(viewsets.ViewSet):
    def list(self, request):
        return Response(['Book1', 'Book2'])
A simple ViewSet with a list method returning a list of books.
Execution Table
StepRequest URLHTTP MethodRouter ActionViewSet Method CalledResponse
1/books/GETMatches 'books' routelist['Book1', 'Book2']
2/books/1/GETMatches 'books' route with pk=1retrieve405 Method Not Allowed (method not implemented)
3/books/POSTMatches 'books' routecreate405 Method Not Allowed (method not implemented)
4/authors/GETNo matching routeNone404 Not Found
💡 Execution stops when response is returned or no matching route is found.
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3After Step 4
request.url/books//books/1//books//authors/
request.methodGETGETPOSTGET
viewset_method_calledlistretrievecreateNone
response['Book1', 'Book2']405 Method Not Allowed405 Method Not Allowed404 Not Found
Key Moments - 3 Insights
Why does a GET request to /books/1/ return 405 Method Not Allowed?
Because the retrieve method is not implemented in the ViewSet, so the router calls it but it returns 405 as default. See execution_table row 2.
Why does a POST request to /books/ return 405 Method Not Allowed?
Because the create method is not implemented in the ViewSet, so the router calls it but it returns 405 by default. See execution_table row 3.
What happens if the URL does not match any route?
The router cannot find a matching route and returns 404 Not Found immediately. See execution_table row 4.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what method does the ViewSet call for a GET request to /books/?
Aretrieve
Blist
Ccreate
Dupdate
💡 Hint
Check the 'ViewSet Method Called' column for Step 1.
At which step does the router fail to find a matching route?
AStep 1
BStep 2
CStep 4
DStep 3
💡 Hint
Look at the 'Router Action' column for each step.
If the create method was added to the ViewSet, what would change at Step 3?
AResponse would be whatever create returns
BResponse would be 404 Not Found
CResponse would be 405 Method Not Allowed
DRouter would not match the URL
💡 Hint
See what happens when a method is implemented in the ViewSet in the execution_table.
Concept Snapshot
ViewSets group related views for a resource.
Routers map URLs to ViewSet methods automatically.
HTTP methods (GET, POST, etc.) select ViewSet actions.
Implement methods like list(), create(), retrieve() in ViewSet.
Router handles URL matching and calls the right method.
Unimplemented methods return 404 or 405 errors.
Full Transcript
In Django REST Framework, ViewSets let you group related views for a resource like books. Routers automatically match URLs to these ViewSets. When a client sends a request, the router checks the URL and HTTP method, then calls the matching method on the ViewSet, such as list for GET /books/. If a method like retrieve or create is not implemented, the router returns 404 or 405 errors. This flow helps organize code and reduces URL configuration.

Practice

(1/5)
1. What is the main purpose of using ViewSets in Django REST Framework?
easy
A. To group common web actions like list, create, update, and delete in one class
B. To define database models for the API
C. To write custom HTML templates for views
D. To handle user authentication manually

Solution

  1. Step 1: Understand what ViewSets do

    ViewSets group common actions such as list, create, update, and delete into one class to simplify API views.
  2. Step 2: Compare with other options

    Options B, C, and D describe unrelated tasks: models, templates, and authentication, which are not the main purpose of ViewSets.
  3. Final Answer:

    To group common web actions like list, create, update, and delete in one class -> Option A
  4. Quick Check:

    ViewSets group actions = A [OK]
Hint: ViewSets bundle common API actions together [OK]
Common Mistakes:
  • Confusing ViewSets with models
  • Thinking ViewSets handle templates
  • Assuming ViewSets manage authentication
2. Which of the following is the correct way to register a ViewSet with a router in Django REST Framework?
easy
A. router.attach('items', ItemViewSet)
B. router.add('items', ItemViewSet)
C. router.register('items', ItemViewSet)
D. router.include('items', ItemViewSet)

Solution

  1. Step 1: Recall the router method to register ViewSets

    The correct method to register a ViewSet with a router is register().
  2. Step 2: Verify method names

    Methods like add(), include(), and attach() do not exist on routers for this purpose.
  3. Final Answer:

    router.register('items', ItemViewSet) -> Option C
  4. Quick Check:

    Use register() to add ViewSets to routers [OK]
Hint: Use router.register() to add ViewSets [OK]
Common Mistakes:
  • Using non-existent router methods like add or include
  • Confusing router registration with URL inclusion
  • Forgetting to pass the ViewSet class
3. Given this code snippet, what URL patterns will be automatically created by the router?
from rest_framework import routers

router = routers.DefaultRouter()
router.register('books', BookViewSet)
medium
A. /books/list/ for list, /books/create/ for create
B. /books/viewset/ for all actions
C. /books/all/ for all actions
D. /books/ for list and create, /books/{pk}/ for retrieve, update, delete

Solution

  1. Step 1: Understand DefaultRouter URL patterns

    DefaultRouter creates URLs like /books/ for listing and creating, and /books/{pk}/ for retrieve, update, and delete actions.
  2. Step 2: Compare with other options

    Options A, C, and D use incorrect URL paths that are not generated by DefaultRouter automatically.
  3. Final Answer:

    /books/ for list and create, /books/{pk}/ for retrieve, update, delete -> Option D
  4. Quick Check:

    DefaultRouter creates standard REST URLs = B [OK]
Hint: DefaultRouter creates /resource/ and /resource/{id}/ URLs [OK]
Common Mistakes:
  • Expecting custom URL suffixes like /list or /create
  • Not knowing DefaultRouter auto-generates URLs
  • Confusing URL patterns with manual URL configs
4. Identify the error in this router registration code:
from rest_framework import routers

router = routers.DefaultRouter()
router.register('authors', authorsViewSet)
medium
A. The ViewSet class name should be capitalized as AuthorsViewSet
B. The router should be SimpleRouter, not DefaultRouter
C. The register method requires a third argument for basename
D. The URL prefix 'authors' is invalid

Solution

  1. Step 1: Check the ViewSet class name

    Python class names should be capitalized. 'authorsViewSet' is likely a typo and should be 'AuthorsViewSet'.
  2. Step 2: Validate other options

    DefaultRouter is valid here, basename is optional if ViewSet has queryset, and 'authors' is a valid URL prefix.
  3. Final Answer:

    The ViewSet class name should be capitalized as AuthorsViewSet -> Option A
  4. Quick Check:

    Class names must be capitalized = A [OK]
Hint: Class names must start with uppercase letter [OK]
Common Mistakes:
  • Using lowercase for class names
  • Thinking basename is always required
  • Confusing router types unnecessarily
5. You want to create a router that registers two ViewSets: ProductViewSet and CategoryViewSet. You also want to customize the basename for CategoryViewSet because it has no queryset attribute. Which code snippet correctly does this?
hard
A. router.register('products', ProductViewSet) router.register('categories', CategoryViewSet)
B. router.register('products', ProductViewSet) router.register('categories', CategoryViewSet, basename='category')
C. router.register('products', ProductViewSet, basename='product') router.register('categories', CategoryViewSet)
D. router.register('products', ProductViewSet, basename='products') router.register('categories', CategoryViewSet, basename=CategoryViewSet)

Solution

  1. Step 1: Understand basename usage

    If a ViewSet lacks a queryset attribute, you must provide a basename when registering it with the router.
  2. Step 2: Check the code snippets

    router.register('products', ProductViewSet) router.register('categories', CategoryViewSet, basename='category') correctly registers ProductViewSet without basename (assuming it has queryset) and CategoryViewSet with basename='category'. Other options either omit basename or misuse it.
  3. Final Answer:

    router.register('products', ProductViewSet) router.register('categories', CategoryViewSet, basename='category') -> Option B
  4. Quick Check:

    Provide basename if no queryset = C [OK]
Hint: Add basename if ViewSet has no queryset [OK]
Common Mistakes:
  • Omitting basename for ViewSets without queryset
  • Using wrong basename strings
  • Adding basename unnecessarily