Setting Up urls.py with Routers in Django REST Framework

Last updated 2 weeks, 6 days ago | 82 views 75     5

Tags:- Python Django DRF

In Django REST Framework, organizing your API routes efficiently is essential for maintainable and scalable projects. One of the best ways to handle API routing is through routers, which work hand-in-hand with ViewSets to automatically generate URLs for your API.

In this article, you'll learn:

  • Why use routers in urls.py

  • How routers work with ViewSet

  • A complete urls.py example

  • Common practices and pitfalls


Why Use Routers?

Traditionally, in Django you define routes manually:

from django.urls import path
from .views import BookListView, BookDetailView

urlpatterns = [
    path('books/', BookListView.as_view()),
    path('books/<int:pk>/', BookDetailView.as_view()),
]

While this works, it becomes repetitive and harder to manage as your API grows.

Enter routers:

  • Automatically map HTTP methods to actions like .list(), .create(), .retrieve()

  • ✅ Cleaner, less error-prone code

  • Especially useful when paired with ViewSet or ModelViewSet


Step-by-Step Setup Using Routers in urls.py

Let’s build a simple Book API using ModelViewSet and routers.

1. Define the Model

# models.py
from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=100)

2. Create a Serializer

# serializers.py
from rest_framework import serializers
from .models import Book

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'

3. Create a ViewSet

# views.py
from rest_framework.viewsets import ModelViewSet
from .models import Book
from .serializers import BookSerializer

class BookViewSet(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

4. Configure urls.py with Router

# urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import BookViewSet

router = DefaultRouter()
router.register(r'books', BookViewSet, basename='book')

urlpatterns = [
    path('api/', include(router.urls)),
]

✅ This code registers the BookViewSet with the router.

The router automatically provides these endpoints:

Method URL Action
GET /api/books/ List all books
POST /api/books/ Create a new book
GET /api/books/<pk>/ Retrieve a book
PUT /api/books/<pk>/ Update a book
PATCH /api/books/<pk>/ Partially update a book
DELETE /api/books/<pk>/ Delete a book

Explanation of Parameters

router.register(r'books', BookViewSet, basename='book')
  • r'books': The URL prefix (e.g., /api/books/)

  • BookViewSet: The viewset class

  • basename='book': DRF uses this to name the routes if .queryset is not defined


⚠️ Common Pitfalls

Problem Solution
URL not found Ensure include(router.urls) is in urlpatterns
API root not displaying Use DefaultRouter instead of SimpleRouter
Duplicate or missing URLs Don’t register the same viewset twice
Missing trailing slash error Check your APPEND_SLASH setting or use consistent URLs

Best Practices

  • ✅ Use DefaultRouter for auto-generated root and easier debugging

  • ✅ Group all API routes under a common prefix like 'api/'

  • ✅ Use basename if you’re not using .queryset in your viewset

  • ✅ Keep your urls.py clean and DRY (don’t repeat yourself)


Summary

Feature Benefit
Routers in urls.py Automatically generate clean, RESTful URLs
DefaultRouter Adds root view and full CRUD URL patterns
include(router.urls) Integrates router with Django's URL dispatcher
basename Helps when queryset isn’t defined in the viewset

Using routers in urls.py makes your API more maintainable, readable, and scalable. It’s the preferred way to connect your ViewSets to URLs in Django REST Framework.


What’s Next?

You might explore:

  • Nested Routers (e.g., drf-nested-routers)

  • Custom Actions in ViewSets with @action

  • Versioning APIs with different routers