суббота, 6 июля 2013 г.

Generic detail view must be called with either an object pk or a slug

Данная ошибка возникает потому, что вы пытаетесь извлечь запись из модели не по значению полей pk (id) или slug.

Вот есть у нас urls.py:

urlpatterns = patterns('',
    # ... какие-то роуты

    url(r'^(?P<slug>\w+)/$', PageView.as_view(), name='page_detail'),
)

А вот у нас представление во views.py:

class PageView(DetailView):
    
    template_name = 'page_detail.html'
    context_object_name = 'page'
    model = Page

Здесь мы указываем модель Page, из которой должна доставаться запись для детального отображения.
Кстати, вот как выглядит модель Page в models.py:

class Page(models.Model):
    """
    Страница сайта
    """
    title = models.CharField(max_length=50, verbose_name='Заголовок')
    slug = models.SlugField(verbose_name='URL страницы', help_text='Например, uslugi', unique=True)
    content = models.TextField(verbose_name='Содержание')

    def __unicode__(self):
        return self.title

    class Meta:
        verbose_name = 'Страница'
        verbose_name_plural = 'Страницы'

Очень важно добавить в модель поле с названием slug, если мы хотим с его помощью получать детальные представления модели.
Теперь мы можем получать контент определенной страницы, обращаясь по адресам:
http://mysite.ru/uslugi       (будет загружена страница, имеющая slug = uslugi)
http://mysite.ru/contacts   (будет загружена страница, имеющая slug = contacts)

Эти url выглядят понятнее для пользователя, чем:
http://mysite.ru/1
http://mysite.ru/2

Но если вы все-таки хотите, чтобы детальное представление ваших страниц было доступно по этим числовым роутам, просто укажите в urls.py:

urlpatterns = patterns('',
    # ... какие-то роуты

    url(r'^(?P<pk>\d+)/$', PageView.as_view(), name='page_detail'),
)

В таком случае поле slug в модели Page вам не понадобится, ведь детальные записи будут доставаться по полю pk (primary key).

Комментариев нет:

Отправить комментарий