Как я могу получить "pk" или "id" в `get_context_data` из CVB?

Как я могу получить 'pk' или 'id' в get_context_data из CVB 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'),

Ответ 1

Вы можете получить его от self.kwargs['pk'].

Я не уверен, почему вы хотите, тем не менее, поскольку суперкласс уже получает книгу, соответствующую этому pk, - что вся точка DetailView.

Ответ 2

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

Ответ 3

В get_context_data у вас уже есть объект в self.object(и вы можете сделать self.object.pk). Вот что происходит вверх по иерархии классов (DetailView наследует от 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)

Чтение исходного кода Django для понимания вещей невероятно просто.

И, кстати, я не уверен, что вы всегда можете положиться на то, что kwargs имеет ключ "pk".

Ответ 4

В дополнение к тому, чтобы получить его от self.kwargs, как предложил Daniel Roseman, вы можете использовать self.get_object().pk, например, если вы измените свой идентификатор URL из pk, скажем, slug или что-то в этом роде.

Ответ 5

вы можете просто получить его в методе "get", например:

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

Ответ 6

self.kwargs['pk'] это не работает в Django 2.2

в DetailView

self.object - это объект, который отображает это представление.

Таким образом, для доступа к полям объекта, таким как id или pk, просто self.object.id или self.object.pk

Итак, ответ в Django 2.2 может быть таким:

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

Django 2.2 Doc