Django: generic detail view must be called with either an object pk or a slug in the URLconf
April 23, 2021 ‐ 2 min read
There is great magic involved in Django its class-based views, the good kind of magic. The kind of magic that saves me lots of time and lines of code. However, using them requires you to follow some conventions.
Such a conventions in Django is using properly named url variables when using detail views. View classes like
UpdateView rely on the presence of either a url variable with the name
slug. These classes inherit a method called
get_object from the
SingleObjectMixin class. This
get_object method is used to find the right model instance to be displayed in the view.
So lets consider the following example: a detail view for a blog post model.
# blog/views.py from django.views import generic from blog.models import Post class DetailView(generic.DetailView): model = Post template_name = 'blog/detail.html'
In order to comply with the requirements from the
get_object method we should add a url containing a variable named either
slug. Otherwise we would get an
AttributeError from Django with the message:
Generic detail view DetailView must be called with either an object pk or a slug in the URLconf.
When using the
path() function you should keep the following format in mind when adding url variables:
<variable type:variable name>.
If you prefer to use the primary key for you DetailView you should add it in the
# urls.py from django.urls import path from blog import views urlpatterns = [ path('<int:pk>/', views.DetailView.as_view()), ]
If you prefer to use a slug for your DetailView you should first make sure your model implements a SlugField. Then add the slug as
<slug:slug>, bit confusing maybe but both the variable type and name are supposed to be named
# urls.py from django.urls import path from blog import views urlpatterns = [ path('<slug:slug>/', views.DetailView.as_view()), ]