Django - 如何使“临时”slug正常工作并获取永久链接
我正在尝试在我的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-]+
或者类似的写法。