slaughterize slaughterize - 22 days ago 11
Python Question

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

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()

Answer

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

Just to take an example from your 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.

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