在URL中显示slug和ID,但仅在Django中按ID进行路由

时间:2014-02-17 11:29:50

标签: django django-urls slug django-1.5 pretty-urls

我想要实现的是:我的新闻应用程序应该显示一个slug,但只能通过ID以 / news / 24 / this-is-the-slug 的形式查询文章

不幸的是,我在尝试浏览文章时遇到了NoReverseMatch: Reverse for 'news_detail' with arguments '('',)' and keyword arguments '{}' not found.。如上所述,模板中生成的URL看起来是正确的(我可以通过Haystack进行搜索来确认这一点,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.`

2 个答案:

答案 0 :(得分:3)

感谢@Daniel Roseman和@yuvi。在您的帮助下,我设法通过定义URL模式来解决我的问题:

r'^(?P<pk>\d+)(?:/(?P<slug>[\w\d-]+))?/$',

允许我所有想要的形式

  • 新闻/ NN
  • 新闻/ NN /
  • 新闻/ NN /α-蛞蝓
  • 新闻/ NN /α-蛞蝓/

在模板中,我使用

{% url 'news_detail' news.id news.prettyurl %}

其中显示了上面列表中的第四个版本。

再次感谢!

答案 1 :(得分:1)

我不太确定你为什么要费心去捕捉slu ..而不是在URL模式中有一个命名组,你可以只有一个忽略PK后的所有内容:

r'^(?P<pk>\d+)/.*',

无论你是否通过了slug,它都可以正常工作,这样你就可以摆脱重复的模式。

但是,你有两个基本问题。首先,即使你声明你只想在PK上实际匹配,你甚至都不会将PK传递给URL,只有slug。其次,即使slug看起来是空白的,因为错误消息表明(args变量只是'')。

你应该通过实际的PK:

{% url 'news_detail' news.pk %}