Tms91
Tms91

Reputation: 4184

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

I am building an app in Django, it uses class based views.

In my views.py I have this class based view that allows to inspect details of objects in my model 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

As I try to run the server I get this traceback:

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

What is the problem?

Upvotes: 0

Views: 10081

Answers (2)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476669

As you derived yourself, the type should be an element of the Method Resolution Order (MRO) of self, so:

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

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

however, since , you do not need to pass parameter to super(): If you are using the class where it is defined, and self as parameter, you can make use of super(), so you can rewrite this to:

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

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

This thus makes it easy to define a code fragment that can be easily copy pasted to other views.

Furthermore here it makes no sense to override get_context_data, since you only call the super method and return its result, you can ommit the override.

Upvotes: 2

Tms91
Tms91

Reputation: 4184

SOLVED

The traceback says

obj must be an instance or subtype of type

pointing at super(type, obj)

This means that the second argument that you pass to super must be an instance or subtype of the first one.

If you look at your code, ProductListView is not an instance or subtype of self, that in the case is equal to ProductDetailView.

This is obviously a bad copy-paste issue. Replace

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

with

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

Upvotes: 0

Related Questions