class based views -TypeError: super(type, obj): obj must be an instance or subtype of type

class based views -TypeError: super(type, obj): obj must be an instance or subtype of type

我正在用 Django 构建一个应用程序,它使用基于 class 的视图。

在我的 views.py 中,我有这个基于 class 的视图,允许检查模型中对象的细节 Product:

class ProductDetailView(DetailView):
    queryset = Product.objects.all()
    template_name = "products/detail.html"

    def get_context_data(self, *args, **kwargs):
        context = super(ProductListView, self).get_context_data(*args, **kwargs)
        return context

当我尝试 运行 服务器时,我得到了这个回溯:

Traceback (most recent call last):
...
context = super(ProductListView, self).get_context_data(*args, **kwargs)
TypeError: super(type, obj): obj must be an instance or subtype of type

有什么问题?

已解决

回溯说

obj must be an instance or subtype of type

指向super(type, obj)

这意味着您传递给 super 的第二个参数必须是第一个参数的实例或子类型。

如果您查看您的代码,ProductListView 不是 self 的实例或子类型,在这种情况下等于 ProductDetailView

这显然是一个糟糕的复制粘贴问题。替换

context = super(ProductListView, self).get_context_data(*args, **kwargs)

context = super(ProductDetailView, self).get_context_data(*args, **kwargs)

因为你自己导出,类型应该是 selfMethod Resolution Order (MRO) 的一个元素,所以:

class ProductDetailView(DetailView):
    queryset = Product.objects.all()
    template_name = 'products/detail.html'

    def get_context_data(self, *args, **kwargs):
        context = super(<b>ProductDetailView</b>, self).get_context_data(*args, **kwargs)
        return context

然而,由于 ,您 不需要 将参数传递给 super():如果您使用 class已定义,并且 self 作为参数,您可以使用 super(),因此您可以将其重写为:

class ProductDetailView(DetailView):
    queryset = Product.objects.all()
    template_name = 'products/detail.html'

    def get_context_data(self, *args, **kwargs):
        context = <b>super()</b>.get_context_data(*args, **kwargs)
        return context

这样可以轻松定义可以轻松复制粘贴到其他视图的代码片段。

此外,这里覆盖 get_context_data 没有任何意义,因为您只调用超级方法和 return 它的结果,您可以忽略覆盖。