Reputation: 343
How can I get 'pk' or 'id' in get_context_data
from CBV DetailView?
class MyDetail(DetailView):
model = Book
template_name = 'book.html'
def get_context_data(self, **kwargs):
context = super(MyDetail, self).get_context_data(**kwargs)
context['something'] = Book.objects.filter(pk=pk)
return context
url:
url(r'^book/(?P<pk>\d+)/$', MyDetail.as_view(), name='book'),
Upvotes: 34
Views: 43150
Reputation: 11
def get_context_data(self, request, pk, *args, **kwargs):
context = super(MyDetail, self).get_context_data(**kwargs)
context['something'] =Book.objects.filter(pk=self.kwargs.get('pk'))
return context
Filter returns a query set that matches the lookup parameter (pk). Since 'pk' is unique, it would return the same results as get but for performance issues, ideally you'd want to use the get method to return one single object:
def get_context_data(self, request, pk, *args, **kwargs):
context = super(MyDetail, self).get_context_data(**kwargs)
context['something'] =Book.objects.get(pk=self.kwargs.get('pk'))
return context
Upvotes: 1
Reputation: 5498
self.kwargs['pk']
it doesn't work in Django 2.2
in DetailView
self.object is the object that this view is displaying.
So, to access the object's fields like
id
orpk
justself.object.id
orself.object.pk
So, The answer in Django 2.2 can be like:
class MyDetail(DetailView):
model = Book
template_name = 'book.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['something'] = Book.objects.filter(pk=self.object.pk) # <<<---
return context
Upvotes: 7
Reputation: 990
you can simply get it in the 'get' method, like this:
def get_context_data(self, request, pk, *args, **kwargs):
context = super(MyDetail, self).get_context_data(**kwargs)
context['something'] =Book.objects.filter(pk=self.kwargs.get('pk'))
return context
Upvotes: 3
Reputation: 394
class MyDetail(DetailView):
model = Book
template_name = 'book.html'
def get_context_data(self, **kwargs):
context = super(MyDetail, self).get_context_data(**kwargs)
context['something'] =Book.objects.filter(pk=self.kwargs.get('pk'))
return context
Upvotes: 8
Reputation: 17243
In addition to getting it from self.kwargs
as Daniel Roseman suggested, you can use self.get_object().pk
, for example if you change your URL identifier from pk
to, say, slug
or something.
Upvotes: 3
Reputation: 318
In get_context_data you already have the object in self.object (and you can do self.object.pk). Here's what happens upstream in the class hierarchy (DetailView inherits from BaseDetailView):
class BaseDetailView(SingleObjectMixin, View):
"""
A base view for displaying a single object
"""
def get(self, request, *args, **kwargs):
self.object = self.get_object()
context = self.get_context_data(object=self.object)
return self.render_to_response(context)
Reading Django source code to understand stuff is incredibly easy.
And by the way, I am not sure you can always rely on the fact that kwargs has a 'pk' key.
Upvotes: 5
Reputation: 599450
You can get it from self.kwargs['pk']
.
I'm not sure why you want to, though, since the superclass already gets the Book corresponding to that pk - that's the whole point of a DetailView.
Upvotes: 64