Django - 如何使“临时”slug正常工作并获取永久链接

4 投票
1 回答
1963 浏览
提问于 2025-04-15 15:04

我正在尝试在我的Django应用中为网址添加“slug”,就像Stack Overflow那样。

目前,我有一些页面,它们的网址格式很好,比如这样:

http://example.com/foo/123/

我想添加“slugified”(即经过处理的)网址,像这样:

http://example.com/foo/123/foo-name-here

我可以通过简单地修改网址配置(urlconf)并在视图函数中添加一个临时值来让它正常工作:

#urls.py

ulpatterns = patterns('project.app.views',
    url(r'^foo/(?P<foo_id>\d+)/(?P<name_slug>\w+)/$', 'foo_detail', name='foo_detail'),
)

#views.py:

def foo_detail(request, foo_id, name_slug):
    # stuff here, name slug is just discarded

访问带有slug的网址也能正常使用。

但是,我的问题出现在使用 @models.permalink 的时候。

对于我的 Foo 模型,我之前有以下代码,这个是可以正常工作的:

@models.permalink
def get_absolute_url(self):
    return ('foo_detail', [str(self.id),])

但是,在我做了修改后,每当我在模板中调用 {{ foo.get_absolute_url }} 时,结果总是一个空字符串。

我尝试了以下两种替代方案来替换 get_absolute_url,但都没有成功:

from django.template.defaultfilters import slugify

# attempt 1
@models.permalink
def get_absolute_url(self):
    return ('foo_detail', [str(self.id), slugify(self.name)])

# attempt 2
@models.permalink
def get_absolute_url(self):
    return ('foo_detail', (), {
        'foo_id': str(self.id), 
        'name_slug': slugify(self.name),
    })

注意,如果我在返回之前加上 print slugify(self.name),控制台中会正确显示处理后的名字。

但是在我的模板中调用 {{ foo.get_absolute_url }} 时,结果总是空字符串,而且没有任何错误提示。

我知道我可以用 return '/foo/%s/%s' % (str(self.id), slugify(self.name)) 来替换这个方法,但我想让永久链接正常工作,这样我的网址只在一个地方定义。我到底哪里做错了呢?

1 个回答

7

有一点需要注意,因为我也遇到过这个问题:

(?P<name_slug>\w+)

就是要检查一下slugify是不是在某个地方加了连字符(-)?如果加了的话,正则表达式就匹配不上了,因为连字符算是非字母字符。要解决这个问题,可以用 [\w-]+ 或者类似的写法。

撰写回答