2014-02-17 6 views
7

Я пытаюсь достичь: мое приложение новостей должно отображать slug, но только запрашивать статью по ID в виде /news/24/this-is-the slugОтображение как slug, так и ID по URL-адресу, но маршрут по ID только в Django

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

Если вам не нужен пул, а только идентификатор, тогда нет причин передавать его в качестве аргумента для представления, верно? – yuvi

ответ

2

Спасибо @Daniel Роземан и @yuvi. С вашей помощью мне удалось решить мою проблему, определив шаблон URL для этого:

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

, который позволяет все мои разыскиваемые формы

  • новости/пп
  • Новости/NN/
  • новости/пп/а-слизняк
  • новости/пп/а-слизняк/

В шаблон, я использую

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

Какой показывает четвертую версию в списке выше.

Еще раз спасибо!

+1

вы также можете использовать' {% url' news_detail 'news.id news .title | slugify%} ' – JuanPablo

+0

, но с помощью этого решения вы можете получить контент с помощью'/news/24/this-is-the-slug' или с '/ news/24/dadadsdasdas' – JuanPablo

+0

Да, но это было мое намерение , Идентификатор предназначен для запросов, slug - только глазная конфета. – weeheavy

1

Я не совсем уверен, почему вы потрудившись захватить слизняка на всех. Вместо того, именованная группа в структуре URL, вы можете просто иметь один, который игнорирует все после PK:

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

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

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

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

{% url 'news_detail' news.pk %} 
+2

Хотя я согласен, что ему не нужно ловить слизню, шаблон url '/.*' не * игнорирует * остальные. На самом деле это наоборот, он поймает почти все, что вы бросаете на него, предоставляя вам '/ number /' перед ним. Такой образ обычно следует избегать (я так думаю), но когда это необходимо, он должен появляться как последний шаблон url, чтобы избежать возможности получения запросов, предназначенных для похожих шаблонов, которые более специфичны (т. Е. Такой шаблон, как ' r '^ (? P \ d +)/(? P \ d +)/$ 'будет проглочен, если он не появится первым) – yuvi

Смежные вопросы