Python 将 Pk 或 Slug 传递给 Django 中的通用 DetailView?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31947764/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Passing Pk or Slug to Generic DetailView in Django?
提问by Coderaemon
I am new to Django Class based views. I am trying to make a simple view to get details of a post. My views.py:
我是基于 Django 类的视图的新手。我正在尝试制作一个简单的视图来获取帖子的详细信息。我的意见.py:
from django.views.generic import ListView, View, DetailView
class GenreDetail(DetailView):
model = Post
template_name = "post.html"
My urls.py:
我的 urls.py:
urlpatterns = [
url(r'(?P<post_id>[^/]+)', GenreDetail.as_view(), name = 'post'),
url(r'(?P<post_id>[^/]+)/(?P<slug>[-\w]+)$', GenreDetail.as_view()),
]
Error that I get:
我得到的错误:
AttributeError at /2/memtheitroads-of-a-geisha-by-arthur-golden
Generic detail view GenreDetail must be called with either an object pk or a slug.
So the pk or slug is not passed to the Generic Detailview. How do I pass that ? I assume from url it can pick up but it's not.
因此 pk 或 slug 不会传递到通用详细信息视图。我如何通过它?我假设它可以从 url 中提取,但事实并非如此。
采纳答案by Anentropic
url patterns are checked in the order you define them
url 模式按照您定义的顺序进行检查
so here:
所以在这里:
urlpatterns = [
url(r'(?P<post_id>[^/]+)', GenreDetail.as_view(), name = 'post'),
url(r'(?P<post_id>[^/]+)/(?P<slug>[-\w]+)$', GenreDetail.as_view()),
]
...the first pattern is getting matched (because it does not end with $
so the extra segment is just ignored)
...第一个模式正在匹配(因为它没有以结尾,$
所以额外的部分被忽略了)
...and that pattern only passes a single keyword arg
...并且该模式只传递一个关键字 arg
Generally it is a bad idea to have multiple url patterns pointing to the same view. If possible you should try and make a single regex (eg using optional groups) which handles the various cases of the url for a particular view. It's more explicit that way.
一般来说,让多个 url 模式指向同一个视图是一个坏主意。如果可能,您应该尝试制作一个正则表达式(例如使用可选组)来处理特定视图的 url 的各种情况。这样更明确。
On the other hand, simply reversing the order of your patterns to put the more explicit one first would also work and be correct (this is the Django rule of urlpatterns!)
另一方面,简单地颠倒模式的顺序以将更明确的模式放在第一位也可以工作并且是正确的(这是 urlpatterns 的 Django 规则!)
urlpatterns = [
url(r'(?P<post_id>[^/]+)/(?P<slug>[-\w]+)$', GenreDetail.as_view()),
url(r'(?P<post_id>[^/]+)', GenreDetail.as_view(), name = 'post'),
]
As @ozgur mentions you also need to tell the view to use post_id
instead of pk
by setting pk_url_kwarg
正如@ozgur 提到的,您还需要告诉视图使用post_id
而不是pk
通过设置pk_url_kwarg
回答by ozgur
The problem is that you have to tell DetailView
that it should use post_id
keyword in the URL instead of default ones pk
or slug
in order to get the object that will be displayed.
问题是您必须告诉DetailView
它应该post_id
在 URL 中使用关键字而不是默认关键字,pk
或者slug
为了获取将显示的对象。
This can be done by setting pk_url_kwarg
attribute:
这可以通过设置pk_url_kwarg
属性来完成:
(Your url definition is also wrong, always end your url definitions with $
. Below is the corrected version)
(您的 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()),
The following urls will match given the url patterns above:
根据上面的 url 模式,以下 url 将匹配:
- /2
- /2/memtheitroads-of-a-geisha-by-arthur-golden
- /2
- /2/艺伎回忆录 by-arthur-golden
from django.views.generic import DetailView
class GenreDetail(DetailView):
model = Post
template_name = "post.html"
pk_url_kwarg = "post_id"
Alternatively, you can just change post_id
to pk
in your url so you don't have to touch anything in your view:
或者,您可以在 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()),
回答by Rajesh Kaushik
If you want to fetch details using either post_id or slug then your urls should be like this
如果您想使用 post_id 或 slug 获取详细信息,那么您的网址应该是这样的
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'),
And your view should be like this
你的观点应该是这样的
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
For more details please read the docs.
有关更多详细信息,请阅读文档。