DRF Router Cheat Sheet Dashboard
✅ SimpleRouter
A lightweight router that maps basic CRUD operations.
| URL | Method | Action | Name |
|---|---|---|---|
| {prefix}/ | GET | list | {basename}-list |
| {prefix}/ | POST | create | - |
| {prefix}/{lookup}/ | GET | retrieve | {basename}-detail |
| {prefix}/{lookup}/ | PUT | update | - |
| {prefix}/{lookup}/ | PATCH | partial_update | - |
| {prefix}/{lookup}/ | DELETE | destroy | - |
✅ DefaultRouter
Extends SimpleRouter with an API root and format suffixes.
| URL | Method | Action | Name |
|---|---|---|---|
| [.format] | GET | API Root | api-root |
| {prefix}/[.format] | GET | list | {basename}-list |
| {prefix}/[.format] | POST | create | - |
| {prefix}/{lookup}/[.format] | GET | retrieve | {basename}-detail |
| {prefix}/{lookup}/[.format] | PUT | update | - |
| {prefix}/{lookup}/[.format] | PATCH | partial_update | - |
| {prefix}/{lookup}/[.format] | DELETE | destroy | - |
🔗 Quick Comparison Table
| Feature | SimpleRouter | DefaultRouter | Custom Router |
|---|---|---|---|
| CRUD Actions | ✅ | ✅ | ✅ (customizable) |
| API Root View | ❌ | ✅ | ❌ (manual) |
| Format Suffixes | ❌ | ✅ | ❌ |
| Trailing Slash Control | ✅ | ✅ | ✅ |
| Custom Path Rules | ❌ | ❌ | ✅ |
🌐 SimpleRouter URL Patterns
| URL | Method | Action | Name |
|---|---|---|---|
| {prefix}/ | GET | list | {basename}-list |
| {prefix}/{lookup}/ | GET | retrieve | {basename}-detail |
🌐 DefaultRouter URL Patterns
| URL | Method | Action | Name |
|---|---|---|---|
| {prefix}/[.format] | GET | list | {basename}-list |
| {prefix}/{lookup}/[.format] | GET | retrieve | {basename}-detail |
🛠️ Key Router Methods
| Method | Purpose |
|---|---|
| get_urls() | Defines URL patterns. |
| get_default_basename() | Auto-generates basename. |
| self.registry | Stores (prefix, viewset, basename). |
🔗 Comparison Table
| Feature | SimpleRouter | DefaultRouter |
|---|---|---|
| CRUD Actions | ✅ | ✅ |
| API Root View | ❌ | ✅ |
| Format Suffixes | ❌ | ✅ |
| Custom Path Rules | ❌ | ❌ |
💡 Pro Tips
- Disable trailing slashes:
SimpleRouter(trailing_slash=False) - Use UUID lookup:
lookup_value_converter='uuid' - Prefer DefaultRouter if you want an auto API root.
- Use
@actionfor custom viewset logic likeset_password().
💎 Third Party Helpers
| Package | Purpose |
|---|---|
| drf-nested-routers | Nested resources (like /users/5/orders/). |
| wq.db.rest | Auto-registers models like Django Admin. |
| drf-extensions | More router customization. |
🔧 Custom Router Examples
Build your own router when you need to break free of the default behavior.
1️⃣ Add a Global 'health-check' Route
from rest_framework.routers import DefaultRouter
class HealthCheckRouter(DefaultRouter):
def get_urls(self):
urls = super().get_urls()
urls.append(path('health/', self.health_check, name='health-check'))
return urls
def health_check(self, request):
return JsonResponse({'status': 'ok'})
2️⃣ No Trailing Slash Router
from rest_framework.routers import SimpleRouter
class NoSlashRouter(SimpleRouter):
trailing_slash = ''
3️⃣ Custom Router with Global List-All
from rest_framework.routers import SimpleRouter
class ListAllRouter(SimpleRouter):
def get_urls(self):
urls = super().get_urls()
urls.append(path('all/', self.list_all, name='list-all'))
return urls
def list_all(self, request):
return Response({'detail': 'Custom list-all here'})
🚨 Common Pitfalls & How to Dodge Them
- Trailing Slash Confusion: DRF routers love adding slashes. Want none? Set
trailing_slash = ''. - Forgetting to call super().get_urls(): When you override, remember to pull in the parent URLs first!
- Over-customization: If you're rewriting 80% of a router, it might be better to use plain Django URL patterns instead.
- Nested URLs Need Nested Routers: Use
drf-nested-routersinstead of trying to hack it yourself.