Django:将含字符串的URL重定向至含Slug的URL问题
解决分类URL重定向的问题
你的问题核心在于默认的RedirectView无法完成“根据分类名称查找对应slug”的逻辑,而且还存在参数名称不匹配的问题——目标URL期望的是slug参数,但你当前的重定向传递的是category参数,这就导致反向解析失败。
问题拆解
- 你当前的重定向配置只是把捕获到的
category字符串直接传给category视图,但目标URL的参数是slug,反向解析时找不到匹配的参数名,所以报错。 - 即使参数名改对,直接传大写的
Apparel也不是你存储的slug值(比如apparel),必须先从数据库中根据分类名称找到对应的Category对象,拿到它的slug。
解决方案:自定义重定向视图
默认的RedirectView只能做简单的参数传递,没法执行数据库查询,所以我们需要写一个自定义的重定向视图来处理这个逻辑:
1. 编写自定义RedirectView
在deals/views.py中添加以下代码:
from django.views.generic.base import RedirectView from django.urls import reverse from django.shortcuts import get_object_or_404 from .models import Category class CategoryNameToSlugRedirect(RedirectView): permanent = True # 永久重定向,利于SEO def get_redirect_url(self, *args, **kwargs): # 获取URL中传入的分类名称 category_name = kwargs.get('category') # 不区分大小写匹配分类名称(如果需要严格匹配,把__iexact改成=) category = get_object_or_404(Category, name__iexact=category_name) # 反向解析到目标视图,传入正确的slug参数 return reverse('category', kwargs={'slug': category.slug})
2. 更新URL配置
修改deals/urls.py,把原来的重定向路径替换成自定义视图:
from django.urls import path from .views import CategoryNameToSlugRedirect urlpatterns = [ # 替换原来的RedirectView路径 path('category/<str:category>', CategoryNameToSlugRedirect.as_view(), name='category_name_redirect'), # 其他URL配置... ]
3. 优化目标视图(可选但推荐)
你的deals_by_category视图存在潜在的错误:如果没有找到对应slug的Deal,category_deals[0]会抛出IndexError。可以优化成更健壮的版本:
from django.shortcuts import render, get_object_or_404 from .models import Deal, Category def deals_by_category(request, slug): # 先获取分类对象,找不到直接返回404 category = get_object_or_404(Category, slug=slug) # 根据分类过滤Deal category_deals = Deal.objects.filter(category=category).order_by('expired', '-date_added') return render(request, 'deals/category.html', { 'category_deals': category_deals, 'category': category })
效果验证
现在访问/deals/category/Apparel时,自定义视图会:
- 根据
Apparel(不区分大小写)找到对应的Category对象 - 获取该对象的
slug值(比如apparel) - 重定向到
/category/apparel,完美符合你的预期
内容的提问来源于stack exchange,提问作者John Rogerson
相关产品推荐
相关产品推荐

