Python Django:必须使用对象 pk 或 slug 调用通用详细信息视图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23154525/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 02:21:17  来源:igfitidea点击:

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

pythondjango

提问by slaughterize

Getting this error when submitting the form associated with this view. Not sure what exactly is the problem, considering I have a form with a very similar structure and it works fine.

提交与此视图关联的表单时出现此错误。不确定到底是什么问题,考虑到我有一个结构非常相似的表单并且它工作正常。

#views.py
class Facture_Creer(SuccessMessageMixin, CreateView):
    model = Facture
    template_name = "facturation/nouvelle_facture.html"
    form_class= FormulaireFacture

    # permet de retourner a l'URL pointant vers le membre modifie
    def get_success_url(self):
        return reverse_lazy('facture_consulter',kwargs={'pk': self.get_object().id})

class Facture_Update(SuccessMessageMixin, UpdateView):
    model = Facture
    template_name = "facturation/nouvelle_facture.html"
    form_class= FormulaireFacture
    success_message = "Facture mise à jour avec succes"

    # permet de retourner a l'URL pointant vers le membre modifie
    def get_success_url(self):
        return reverse_lazy('facture_consulter',kwargs={'pk': self.get_object().id})

#urls.py
urlpatterns = patterns('',
    url(r'^$', TemplateView.as_view(template_name="facturation/index.html")),
    url(r'^facture/$', FactureView.as_view()),
    url(r'^facture/(?P<id>\d+)', FactureView.as_view(), name='facture_consulter'),
    url(r'^facture/ajouter/$', Facture_Creer.as_view(), name='facture_creer'),
    url(r'^facture/modifier/(?P<pk>\d+)/$', Facture_Update.as_view(), name='facture_update'),
    url(r'^membre/ajouter/$', Membre_Creer.as_view(), name='membre_creer'),
    url(r'^membre/modifier/(?P<pk>\d+)/$', Membre_Update.as_view(), name='membre_update'),
    #url(r'membre/(?P<pk>\d+)/supprimer/$', Membre_Supp.as_view(), name='membre_delete')
)

urlpatterns += staticfiles_urlpatterns()

采纳答案by Alex

You need to pass an object identifier (pk or slug) so your views know which object they're operating on.

您需要传递一个对象标识符(pk 或 slug),以便您的视图知道它们正在操作哪个对象。

Just to take an example from your urls.py:

仅举一个例子urls.py

url(r'^facture/ajouter/$', Facture_Creer.as_view(), name='facture_creer'),
url(r'^facture/modifier/(?P<pk>\d+)/$', Facture_Update.as_view(), name='facture_update'),

See how the second one has (?P<pk>\d+)/? That is passing a pk to the UpdateView so it knows which object to use. Thus if you go to facture/modifier/5/, then the UpdateView will modify object with pk of 5.

看看第二个怎么样了(?P<pk>\d+)/?这就是将 pk 传递给 UpdateView,以便它知道要使用哪个对象。因此,如果您转到facture/modifier/5/,则 UpdateView 将修改 pk 为 5 的对象。

If you don't want to pass a pk or slug in your url, you'll need to override the get_objectmethod and get your object another way. Url here.

如果您不想在 url 中传递 pk 或 slug,则需要覆盖该get_object方法并以另一种方式获取您的对象。网址在这里

回答by Robin

As Alex suggests: for default Django behaviour you have to use "pk" in your url pattern.

正如亚历克斯所建议的那样:对于默认的 Django 行为,您必须在 url 模式中使用“pk”。

If you wish to change the object identifier for the primary key "pk" to a different name, you can define pk_url_kwarg. This is available since Django 1.4.

如果您希望将主键“pk”的对象标识符更改为不同的名称,您可以定义pk_url_kwarg。这从 Django 1.4 开始可用。

回答by Linh

Update: In django 2.0.2, change this to:

更新:在 django 2.0.2 中,将其更改为:

url(r'^facture/modifier/<int:pk>/$', Facture_Update.as_view(), name='facture_update'),

回答by radtek

Hey all I used the new path()function and here is my working example that I'm sure will help:

嘿,我使用了新path()功能,这是我的工作示例,我相信它会有所帮助:

views.py:

视图.py:

from django.views.generic.detail import DetailView

class ContentAmpView(DetailView):

    model = Content
    template_name = 'content_amp.html'  # Defaults to content_detail.html

urls.py:

网址.py:

from django.urls import path

from .views import ContentAmpView

# My pk is a string so using a slug converter here intead of int
urlpatterns = [
    path('<slug:pk>/amp', ContentAmpView.as_view(), name='content-amp'),
]

templates/content_amp.html

模板/content_amp.html

<!doctype html>
<html amp lang="en">
<head>
    <meta charset="utf-8">
    <script async src="https://cdn.ampproject.org/v0.js"></script>
    <title>Hello, AMPs</title>
    <link rel="canonical" href="http://example.ampproject.org/article-metadata.html">
    <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
    <script type="application/ld+json">
      {
        "@context": "http://schema.org",
        "@type": "NewsArticle",
        "headline": "Open-source framework for publishing content",
        "datePublished": "2015-10-07T12:02:41Z",
        "image": [
          "logo.jpg"
        ]
      }

    </script>
    <style amp-boilerplate>
        body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}
    </style>
    <noscript>
        <style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}
        </style>
    </noscript>
</head>
<body>
<h1>Welcome to AMP - {{ object.pk }}</h1>
<p>{{ object.titles.main }}</p>
<p>Reporter: {{ object.reporter }}</p>
<p>Date: {{ object.created_at|date }}</p>
</body>
</html>

Also note that in my settings.py, under TEMPLATES, I have 'APP_DIRS': True. More on path here.

还要注意,在我的settings.py,下TEMPLATES,我有'APP_DIRS': True。更多关于这里的路径。

回答by aldyahsn

Like Robin said, you can use pk_url_kwargif you want custom pk name.

就像 Robin 说的,pk_url_kwarg如果你想要自定义 pk 名称,你可以使用。

But as addition, issue Generic detail view must be called with either an object pk or a slugraises also in slug.

但是作为补充,必须使用对象 pk 或 slug在 slug 中引发问题通用详细信息视图

So if you want to create custom slug field(no need to use pkor slugname). You can override slug_fieldand slug_url_kwargin your DetailView class.

因此,如果您想创建自定义 slug 字段(无需使用pkslug名称)。您可以在 DetailView 类中覆盖slug_fieldslug_url_kwarg

Here is just another example if you want url as Slug Field.

如果您想要 url 作为 Slug Field,这只是另一个示例。

models.py

模型.py

class Post(models.Model):
    title = models.CharField(max_length=255)
    url = models.SlugField()
    body = models.TextField()
    image = models.ImageField(upload_to='blog/', blank=True, null=True)

views.py

视图.py

class ListPost(ListView):
    model = Post
    template_name = 'blog/list.html'
    paginate_by = 2
    context_object_name = 'posts'

class DetailPost(DetailView):
    model = Post
    template_name = 'blog/detail.html'
    slug_field = 'url'
    slug_url_kwarg = 'url'

urls.py

网址.py

urlpatterns = [
    path('', ListPost.as_view()),
    path('<slug:url>/', DetailPost.as_view()),
]

回答by Keerthi

I am using Django version 2.2.12,

我使用的是 Django 2.2.12 版,

Here is just another example this works fine for me :

这只是另一个例子,这对我来说很好用:

models.py

模型.py

from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=256)
    author = models.CharField(max_length=256)
    pages = models.IntegerField()
    price = models.FloatField()

views.py

视图.py

from django.views.generic import ListView,DetailView
from testapp.models import Book

class BookListView(ListView):
    model=Book

class BookDetailView(DetailView):
    model=Book

urls.py

网址.py

from django.contrib import admin
from django.urls import path
from testapp import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.BookListView.as_view()),
    path('<slug:pk>/', views.BookDetailView.as_view()),
]