在Django Rest Framework中构建含年月日与slug的get_absolute_url
解决Django Rest Framework中get_absolute_url的NoReverseMatch错误
问题根源
你的get_absolute_url尝试反转到名为post-detail的路由,并传递了年、月、日、slug四个参数,但当前URL配置中的路由模式仅支持单个参数,导致无法匹配对应路由。
1. 修改URL配置
在博客应用的urls.py中,替换现有的post-detail路由,添加匹配年、月、日、slug的正则模式:
from django.urls import path from . import views urlpatterns = [ # 保留其他现有路由 path('posts/<int:year>/<int:month>/<int:day>/<slug:slug>/', views.post_detail, name='post-detail'), ]
如果使用DRF视图集,需添加自定义路由并保留视图集的其他路由:
from rest_framework.routers import DefaultRouter from . import views router = DefaultRouter() router.register(r'posts', views.PostViewSet) # 添加自定义详情路由 urlpatterns = [ path('posts/<int:year>/<int:month>/<int:day>/<slug:slug>/', views.PostDetailView.as_view(), name='post-detail'), ] + router.urls
2. 确保视图接收并处理参数
函数视图写法
确保视图函数接收四个参数,并通过参数筛选文章:
from django.shortcuts import get_object_or_404 from .models import Post def post_detail(request, year, month, day, slug): post = get_object_or_404(Post, slug=slug, publish__year=year, publish__month=month, publish__day=day, status='published') # 后续逻辑处理
类视图写法(以RetrieveAPIView为例)
重写get_object方法,通过URL参数获取目标文章:
from rest_framework.generics import RetrieveAPIView from django.shortcuts import get_object_or_404 from .models import Post from .serializers import BlogSerializer class PostDetailView(RetrieveAPIView): serializer_class = BlogSerializer def get_object(self): kwargs = self.kwargs return get_object_or_404(Post, slug=kwargs['slug'], publish__year=kwargs['year'], publish__month=kwargs['month'], publish__day=kwargs['day'], status='published')
3. 验证修改
重启Django服务后,访问文章列表页面,get_absolute_url将生成你预期格式的URL(如http://127.0.0.1:8001/blog/posts/2022/10/11/my-post),且点击该URL可正常访问文章详情。
内容的提问来源于stack exchange,提问作者Diaku Zena
相关产品推荐
相关产品推荐

