Displaying both slug and ID in URL, but route by ID only in Django

django, django-1.5, django-urls, pretty-urls, slug

Solution

Thanks @Daniel Roseman and @yuvi. With your help I managed to solve my problem by defining the URL pattern to this:

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

Which allows all my wanted forms of

- news/nn

- news/nn/

- news/nn/a-slug

- news/nn/a-slug/

In the template, I use

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

Which shows the fourth version in the listing above.

Thanks again!

Problem

What I'm trying to achieve is: my News app should display a slug, but only query the article by ID in the form of /news/24/this-is-the-slug Unfortunately I'm getting a `NoReverseMatch: Reverse for 'news_detail' with arguments '('',)' and keyword arguments '{}' not found.` when trying to browse an article. The URL generated in the template looks correct as stated above (I can confirm this by doing a search via Haystack, which delivers the correct 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' ``` Template ``` `<p><a href="{% url 'news_detail' news.slug %}">Permalink</a> for this article.` ```

Original source