web-dev-qa-db-fra.com

Django: La vue de détail générique doit être appelée avec un objet pk ou un slug

Obtenir cette erreur lors de la soumission du formulaire associé à cette vue. Je ne sais pas quel est le problème, étant donné que j’ai un formulaire avec une structure très similaire et que cela fonctionne bien.

#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()
24
slaughterize

Vous devez passer un identifiant d'objet (pk ou slug) pour que vos vues sachent sur quel objet elles opèrent.

Juste pour prendre un exemple de votre 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'),

Voyez comment le second a (?P<pk>\d+)/? Cela passe un pk à UpdateView pour qu'il sache quel objet utiliser. Ainsi, si vous allez à facture/modifier/5/, alors le UpdateView modifiera l'objet avec un pk de 5.

Si vous ne voulez pas passer un pk ou une slug dans votre url, vous devez remplacer la méthode get_object et obtenir votre objet d'une autre manière. Url ici .

32
Alex

Comme Alex le suggère: pour le comportement par défaut de Django, vous devez utiliser "pk" dans votre modèle d'URL.

Si vous souhaitez remplacer l'identifiant d'objet de la clé primaire "pk" par un autre nom, vous pouvez définir pk_url_kwarg . Ceci est disponible depuis Django 1.4.

8
Robin

Bonjour à tous, j’ai utilisé la nouvelle fonction path() et voici mon exemple de travail qui, j'en suis sûr, aidera:

views.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:

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

<!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>

Notez également que dans mon settings.py, sous TEMPLATES, j'ai 'APP_DIRS': True. Plus sur le chemin ici .

0
radtek