You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django 1.5实现URL永久重定向及相关报错解决求助

解决Django 1.5.4中URL永久重定向的NoReverseMatch及属性错误

你遇到的两个错误根源完全一致:你的Activity模型的get_absolute_url()方法错误地返回了HttpResponseRedirect(或类似响应对象),而不是它应该返回的纯URL字符串。Django的redirect()函数和HttpResponsePermanentRedirect都需要接收字符串格式的URL,传入响应对象会直接触发内部处理逻辑出错,也就是你看到的rindex/find属性缺失错误。

第一步:修复get_absolute_url()方法

这是核心问题,必须确保这个方法返回合法的URL字符串,而非响应对象。针对你的新URL格式domain.com/team/event/01-03-2019/827,修改模型方法如下:

from django.core.urlresolvers import reverse
from django.utils.dateformat import format

class Activity(models.Model):
    # 你的模型字段(示例)
    date = models.DateField()
    id = models.AutoField(primary_key=True)

    def get_absolute_url(self):
        # 用reverse生成目标URL字符串,对应你配置的新路由name
        return reverse('activity_details', kwargs={
            'date_url': format(self.date, "d-m-Y"),
            'activity_id': self.id
        })

同时确保urls.py中的新路由已正确命名:

# urls.py 中的新URL配置
urlpatterns = patterns('',
    # 新目标URL:domain.com/team/event/01-03-2019/827
    url(r'^team/event/(?P<date_url>\d{2}-\d{2}-\d{4})/(?P<activity_id>\d+)/$',
        'productions.views.activity_details',
        name='activity_details'),
)

第二步:处理旧URL的永久重定向

现在需要让旧URL(domain.com/team/event-2019/01-03-2019/827)自动重定向到新URL,推荐两种方案:

方案1:单独配置旧URL路由和重定向视图

在urls.py中添加旧URL的路由,指向专门的重定向视图:

# urls.py
urlpatterns = patterns('',
    # 旧URL路由:捕获年份、日期、活动ID
    url(r'^team/event-(?P<year>\d+)/(?P<date_url>\d{2}-\d{2}-\d{4})/(?P<activity_id>\d+)/$',
        'productions.views.old_activity_redirect',
        name='old_activity_redirect'),
    # 保留新URL路由
    url(r'^team/event/(?P<date_url>\d{2}-\d{2}-\d{4})/(?P<activity_id>\d+)/$',
        'productions.views.activity_details',
        name='activity_details'),
)

然后在productions/views.py中添加重定向视图:

from django.shortcuts import get_object_or_404
from django.http import HttpResponsePermanentRedirect
from .models import Activity
from django.utils.dateformat import format

def old_activity_redirect(request, year, date_url, activity_id):
    # 获取对应活动实例
    activity = get_object_or_404(Activity, id=activity_id)
    # 验证日期匹配度(可选,提升严谨性)
    expected_date = format(activity.date, "d-m-Y")
    if date_url != expected_date:
        # 日期不匹配时可重定向到活动列表或返回404
        return HttpResponsePermanentRedirect('/team/events/')
    # 永久重定向到新URL
    return HttpResponsePermanentRedirect(activity.get_absolute_url())

方案2:在现有视图中处理旧URL判断

如果不想新增视图,可以修改现有activity_details的URL路由,允许捕获event_slug参数,然后在视图内判断是否为旧格式:

# 修改urls.py中的新URL路由:
url(r'^team/(?P<event_slug>[^/]+)/(?P<date_url>\d{2}-\d{2}-\d{4})/(?P<activity_id>\d+)/$',
    'productions.views.activity_details',
    name='activity_details'),

更新activity_details视图逻辑:

def activity_details(request, event_slug, date_url, activity_id):
    activity = get_object_or_404(Activity, id=activity_id)
    expected_date = format(activity.date, "d-m-Y")
    
    # 情况1:访问的是旧URL(slug带年份,如event-2019)
    if event_slug.startswith('event-'):
        return HttpResponsePermanentRedirect(activity.get_absolute_url())
    # 情况2:访问新URL但日期不匹配
    elif date_url != expected_date:
        return HttpResponsePermanentRedirect(activity.get_absolute_url())
    
    # 正常执行视图逻辑(渲染模板等)
    # ...
    return render(request, 'productions/activity_details.html', {'activity': activity})

错误原因复盘

  • 第一个NoReverseMatch错误:当你调用redirect(activity.get_absolute_url())时,get_absolute_url()返回的是HttpResponseRedirect对象,而redirect()函数期望接收字符串、视图名或模型实例(内部会调用其get_absolute_url())。Django尝试把这个响应对象当作视图名去执行reverse,但响应对象没有字符串的rindex方法,因此报错。
  • 第二个'find'属性错误:HttpResponsePermanentRedirect需要接收URL字符串作为参数,你传入了HttpResponseRedirect对象,它内部处理URL时会调用字符串的find方法,响应对象没有这个方法,导致报错。

内容的提问来源于stack exchange,提问作者user9192656

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:07:03