在 URL 中同时显示 slug 和 ID,但仅在 Django 中按 ID 路由
Posted
技术标签:
【中文标题】在 URL 中同时显示 slug 和 ID,但仅在 Django 中按 ID 路由【英文标题】:Displaying both slug and ID in URL, but route by ID only in Django 【发布时间】:2014-03-16 16:16:56 【问题描述】:我想要实现的是:我的新闻应用应该显示一个 slug,但只能通过 /news/24/this-is-the-slug 形式的 ID 查询文章
不幸的是,我在尝试浏览文章时收到了NoReverseMatch: Reverse for 'news_detail' with arguments '('',)' and keyword arguments '' not found.
。如上所述,模板中生成的 URL 看起来是正确的(我可以通过 Haystack 进行搜索来确认这一点,它提供了正确的 URL)。
models.py
class News(models.Model):
id = models.IntegerField(primary_key=True, editable=False)
category = models.CharField(max_length=50L)
title = models.CharField(max_length=200L)
rss_summary = models.TextField(max_length=2000L)
body_text = models.TextField(max_length=5000L)
post_date = models.DateTimeField()
prettyurl = models.SlugField(max_length=100L)
class Meta:
db_table = 'news'
def __unicode__(self):
return self.title
def get_absolute_url(self):
return urlresolvers.reverse('news_detail', kwargs='pk': self.id, 'slug': self.prettyurl )
urls.py
urlpatterns = patterns(
'',
url(
r'^$',
view=views.NewsListView.as_view(),
name='news_index'),
url(
r'^(?P<pk>\d+)/',
view=views.NewsDetailView.as_view(),
name='news_detail'),
url(
r'^(?P<pk>\d+)/(?P<slug>[-\w]+)/$',
view=views.NewsDetailView.as_view(),
name='news_detail'),
url(
r'^archive/$',
view=views.NewsArchiveIndexView.as_view(),
name="archive_month"),
[... more unrelated urls ...]
views.py
class NewsDetailView(DetailView):
#name='news_detail'),
model = News
context_object_name = 'news'
#slug_url_kwarg = 'prettyurl'
#slug_field = 'prettyurl'
template_name = 'news/detail.html'
模板
`<p><a href="% url 'news_detail' news.slug %">Permalink</a> for this article.`
【问题讨论】:
如果你不需要 slug,而只需要 id,那么没有理由将它作为参数传递给视图,对吧? 【参考方案1】:感谢@Daniel Roseman 和@yuvi。在您的帮助下,我设法通过定义 URL 模式来解决我的问题:
r'^(?P<pk>\d+)(?:/(?P<slug>[\w\d-]+))?/$',
它允许所有我想要的形式
新闻/nn 新闻/nn/ 新闻/nn/a-slug 新闻/nn/a-slug/在模板中,我使用
% url 'news_detail' news.id news.prettyurl %
上面列出的第四个版本。
再次感谢!
【讨论】:
你也可以使用% url 'news_detail' news.id news.title|slugify %
但使用此解决方案,您可以使用/news/24/this-is-the-slug
或/news/24/dadadsdasdas
获取内容
是的,但那是我的意图。 ID 用于查询,slug 只是养眼。
@weeheavy 正则表达式中的冒号是什么意思?我试图做同样的事情,当我对它进行单元测试时,我也得到了 NoReverseMatch。目前,它在您包含 slug 时有效,但在不包含 slug 时无效。
您还可以使用(?:/(?P<slug>.*))?/$
来允许用户可能放入的其他字符,例如#@%$ 或空格等...【参考方案2】:
我不太确定你为什么要费心去捕捉蛞蝓。您可以只在 PK 之后忽略所有内容,而不是在 URL 模式中使用命名组:
r'^(?P<pk>\d+)/.*',
无论您是否通过了 slug,这同样有效,因此您可以摆脱重复的模式。
但是,您所拥有的存在两个基本问题。首先,即使您声明您只想在 PK 上实际匹配,您甚至不会将 PK 传递给 URL,而只是传递 slug。其次,即使是 slug 似乎也是空白的,因为错误消息指出(args 变量只是 ''
)。
您应该改为传递实际的 PK:
% url 'news_detail' news.pk %
【讨论】:
虽然我同意他不需要抓住蛞蝓,但 url 模式/.*
不会忽略其余部分。事实上恰恰相反,它几乎可以捕捉到你扔给它的任何东西,只要你在它前面有一个/number/
。通常应该避免这种模式(我认为是这样),但在需要时,它应该作为最后一个 url 模式出现,以避免它接收到针对更具体的类似模式的请求的可能性(即,像 @ 这样的模式987654326@不先出现会被吞掉)以上是关于在 URL 中同时显示 slug 和 ID,但仅在 Django 中按 ID 路由的主要内容,如果未能解决你的问题,请参考以下文章
Symfony 5 - 在类别 url 中显示 id 和 slug 并在更新 slug 时通过 id 找到它
Rails 中 URL 中的 ID + Slug 名称(如 *** 中)
在 expss 中创建一个表,显示 freq 和 cpct 但仅在 cpct 列上测试 cpct
Redshift 在多个条件下加入,但仅在一个条件不匹配时返回
Qt 5.4 OS X 如何在 QMenu 和 QToolBar 中使用 QAction,但仅在 QToolbar 中显示图标