【问题标题】:How can I get 'pk' or 'id' in `get_context_data` from CBV?如何从 CBV 获取“get_context_data”中的“pk”或“id”?
【发布时间】:2014-03-12 14:18:56
【问题描述】:

如何从 CBV DetailView 获取 get_context_data 中的“pk”或“id”?

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(r'^book/(?P<pk>\d+)/$', MyDetail.as_view(), name='book'),

【问题讨论】:

  • 在模板中使用,如something.0.pk
  • 我对 CVB 感到困惑,你是指基于类的视图 (CBV) 吗?..

标签: django django-class-based-views


【解决方案1】:
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

过滤器返回与查找参数 (pk) 匹配的查询集。由于 'pk' 是唯一的,它会返回与 get 相同的结果,但出于性能问题,理想情况下您希望使用 get 方法返回一个对象:

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

【讨论】:

    【解决方案2】:

    self.kwargs['pk'] 在 Django 2.2 中不起作用

    在详细视图中

    self.object 是这个视图正在显示的对象。

    因此,要访问对象的字段,例如 idpk,只需 self.object.idself.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

    【讨论】:

      【解决方案3】:

      你可以简单地在'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
      

      【讨论】:

        【解决方案4】:
        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
        

        【讨论】:

          【解决方案5】:

          除了按照 Daniel Roseman 的建议从 self.kwargs 获取之外,您还可以使用 self.get_object().pk,例如,如果您将 URL 标识符从 pk 更改为 slug 或其他内容。

          【讨论】:

            【解决方案6】:

            在 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”键这一事实。

            【讨论】:

              【解决方案7】:

              您可以从self.kwargs['pk'] 获取。

              不过,我不确定您为什么要这样做,因为超类已经获得了与该 pk 对应的 Book - 这就是 DetailView 的全部意义所在。

              【讨论】:

              • 我的查询集看起来不同(更复杂)。 Book.objects.filter(pk=pk) 只是示例。谢谢。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2013-11-25
              • 1970-01-01
              • 2020-05-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-12-01
              相关资源
              最近更新 更多