Отображение slug и ID в URL, но маршрут по ID только в Django

то, что я пытаюсь достичь: мое новостное приложение должно отображать слизень, но только запрашивать статью по ID в виде / Новости / 24 / это-пуля

к сожалению, я получаю 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.`

2 ответов


спасибо @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, вы можете просто иметь ту, которая игнорирует все после PK:

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

который будет работать так же хорошо, независимо от того, прошел ли вы пулю, чтобы вы могли избавиться от своих дублированных шаблонов.

существуют две основные проблемы с тем, что у вас есть, хотя. Во-первых, даже если вы заявляете, что хотите соответствовать только на ПК, вы не даже передайте ПК на URL, просто слизняк. Во-вторых, даже пуля кажется пустой, поскольку в сообщении об ошибке говорится (переменная args просто '').

вместо этого вы должны передать фактический PK:

{% url 'news_detail' news.pk %}