将Pk或Slug传递给Django中的Generic DetailView?

2024-09-26 17:56:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我是Django基于类的视图的新手。我试着做一个简单的视图来获取帖子的细节。 我的观点.py:

from django.views.generic import ListView, View, DetailView 
class GenreDetail(DetailView):
            model = Post
            template_name = "post.html"

我的url.py:

urlpatterns = [
        url(r'(?P<post_id>[^/]+)', GenreDetail.as_view(), name = 'post'),
        url(r'(?P<post_id>[^/]+)/(?P<slug>[-\w]+)$', GenreDetail.as_view()),
    ] 

我得到的错误:

AttributeError at /2/memoirs-of-a-geisha-by-arthur-golden
Generic detail view GenreDetail must be called with either an object pk or a slug.

所以pk或slug不会传递给泛型Detailview。我怎么通过?我想从url可以找到,但不是。


Tags: djangonamepyview视图idurlas
3条回答

url模式按照定义它们的顺序进行检查

所以在这里:

urlpatterns = [
        url(r'(?P<post_id>[^/]+)', GenreDetail.as_view(), name = 'post'),
        url(r'(?P<post_id>[^/]+)/(?P<slug>[-\w]+)$', GenreDetail.as_view()),
    ] 

…正在匹配第一个模式(因为它不以$结尾,所以只忽略多余的段)

…而该模式只传递一个关键字arg

通常,让多个url模式指向同一个视图是一个坏主意。如果可能的话,您应该尝试创建一个regex(例如使用optional groups),用于处理特定视图的url的各种情况。这样就更明确了。

另一方面,简单地颠倒模式的顺序,将更明确的模式放在第一位也可以工作,而且是正确的(这是urlpatterns的Django规则!)

urlpatterns = [
        url(r'(?P<post_id>[^/]+)/(?P<slug>[-\w]+)$', GenreDetail.as_view()),
        url(r'(?P<post_id>[^/]+)', GenreDetail.as_view(), name = 'post'),
    ] 

正如@ozgur提到的,您还需要通过设置^{}告诉视图使用post_id,而不是pk

如果您想使用post-id或slug获取详细信息,那么您的url应该如下所示

url(r'post/(?P<post_id>\d+)/$', GenreDetail.as_view(), name = 'post_detail'),
url(r'post/(?P<slug>[-\w]+)/$', GenreDetail.as_view(), name = 'post_detail_slug'),

你的观点应该是这样的

from django.views.generic import DetailView 

class GenreDetail(DetailView):
    model = Post
    template_name = "post.html"
    pk_url_kwarg = "post_id"
    slug_url_kwarg = 'slug'
    query_pk_and_slug = True

有关详细信息,请阅读docs

问题是您必须告诉DetailView它应该在URL中使用post_id关键字,而不是默认的pkslug关键字,以便获取将要显示的对象。

这可以通过设置^{}属性来完成:

(您的url定义也是错误的,总是以$结束url定义。以下是正确版本)

url(r'(?P<post_id>\d+)$', GenreDetail.as_view(), name = 'post'),
url(r'(?P<post_id>\d+)/(?P<slug>[-\w]+)$', GenreDetail.as_view()),

给定上述url模式,以下url将匹配:

  • /2个
  • /2/艺妓回忆录作者:亚瑟·戈尔德

from django.views.generic import DetailView 

class GenreDetail(DetailView):
    model = Post
    template_name = "post.html"
    pk_url_kwarg = "post_id"

或者,您可以将url中的post_id更改为pk,这样就不必触摸视图中的任何内容:

url(r'(?P<pk>\d+)$', GenreDetail.as_view(), name = 'post'),
url(r'(?P<pk>\d+)/(?P<slug>[-\w]+)$', GenreDetail.as_view()),

相关问题 更多 >

    热门问题