Welcome back to CodeYourCraft! Today, we're diving into one of Django's powerful features: Routers. If you're new to Django, don't worry! We'll cover everything from the ground up.
By the end of this lesson, you'll understand how routers help manage URLs and views in your Django application, and you'll write your own router to handle custom URLs.
In Django, routers are responsible for mapping URLs to views. They help keep your application organized, especially when dealing with complex relationships between models.
Think of routers as the traffic directors of your web app. They guide incoming requests to the correct views, ensuring a smooth experience for users.
Every Django app comes with a default router that maps URLs to views based on your application's models. Let's take a look at how it works:
from django.urls import path
from .models import YourModel
from .views import YourModelView
urlpatterns = [
path('admin/', admin.site.urls),
path('', YourModelView.as_view(), name='your_model_list'),
path('<int:pk>/', YourModelView.as_view(actions={'get': 'retrieve'}), name='your_model_detail'),
]In the above example, we're creating a simple router for a model called YourModel. The default router automatically creates a list view for all YourModel objects and a detail view for a single object based on its primary key (pk).
While the default router is useful, you may want to create custom routers to handle more complex URL structures. Let's create a custom router for a BlogPost model:
from django.urls import re_path, path
from django.contrib.auth.models import User
from django.router.defaults import DefaultRouter
from django.urls.resolvers import URLPattern
class BlogRouter(DefaultRouter):
blog_post_routes = [
re_path(r'^(?P<username>\w+)/$', self.blog_post_list, name='blog_post_list'),
re_path(r'^(?P<username>\w+)/(?P<pk>\d+)/$', self.blog_post_detail, name='blog_post_detail'),
]
def blog_post_list(self, request, username, **kwargs):
user = User.objects.get(username=username)
return self.list(request, 'blogpost', data={'author': user}, **kwargs)
def blog_post_detail(self, request, username, pk, **kwargs):
user = User.objects.get(username=username)
blog_post = get_object_or_404(user.blogpost_set.all(), pk=pk)
return self.retrieve(request, 'blogpost', blog_post, **kwargs)
def get_routes(self):
routes = super().get_routes()
routes += self.blog_post_routes
return routesIn the above code, we've created a custom router called BlogRouter. This router uses regular expressions to match URLs based on the username and primary key of a blog post.
Now that you understand how routers work, let's create a simple blog application using the custom router we just built.
python manage.py startapp blogblog/models.py, define your BlogPost model:from django.db import models
from django.contrib.auth.models import User
class BlogPost(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.titleblog/views.py, create views for the list and detail views of the BlogPost model:from django.views.generic import ListView, DetailView
from .models import BlogPost
class BlogPostList(ListView):
model = BlogPost
class BlogPostDetail(DetailView):
model = BlogPostblog/urls.py to use the custom router:from django.urls import path
from . import views
from .routers import BlogRouter
router = BlogRouter()
urlpatterns = [
path('admin/', admin.site.urls),
] + router.urlspython manage.py runserverNow, if you navigate to http://127.0.0.1:8000/your_username/, you'll see your custom blog list!
What is the main purpose of routers in Django?
How can you create a custom router in Django?