Setting Up urls.py with Routers in Django REST Framework
Last updated 2 weeks, 6 days ago | 82 views 75 5

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
orModelViewSet
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