super(type, obj): obj must be an instance or subtype of type
I work on a small Django
app and get an error tells me, super(type, obj): obj must be an instance or subtype of type
. I get it from the views.py
file after introducing the function get_object_or_404
. The views.py
file provided below,
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from django.views import View
from .models import URL
# function based view
def redirect_view(request, shortcode=None, *args, **kwargs):
obj = get_object_or_404(URL, shortcode=shortcode)
return HttpResponse("Hello World, the shortcode is {shortcode}".format(shortcode = obj.url))
# class based view
class ShortenerView(View):
def get(self, request, shortcode=None, *args, **kwargs):
obj = get_object_or_404(URL, shortcode=shortcode)
return HttpResponse("Hello World 1, the shortcode is {shortcode}".format(shortcode = obj.url))
def post(self, request, *args, **kwargs):
return HttpResponse()
the full error message is here,
TypeError at /b/p6jzbp/
super(type, obj): obj must be an instance or subtype of type
Request Method: GET
Request URL: http://127.0.0.1:8000/b/p6jzbp/
Django Version: 1.11
Exception Type: TypeError
Exception Value:
super(type, obj): obj must be an instance or subtype of type
Exception Location: /Users/Chaklader/Documents/Projects/UrlShortener/src/shortener/models.py in all, line 18
The line 18
in the models.py
is qs_main = super(URL, self).all(*args, **kwargs)
and the models.py
file is here,
# will look for the "SHORTCODE_MAX" in the settings and
# if not found, will put the value of 15 there
SHORTCODE_MAX = getattr(settings, "SHORTCODE_MAX", 15)
class UrlManager(models.Manager):
def all(self, *args, **kwargs):
qs_main = super(URL, self).all(*args, **kwargs)
qs = qs_main.filter(active = True)
return qs
def refresh_shortcodes(self, items = None):
qs = URL.objects.filter(id__gte=1)
new_codes = 0
if items is not None and isinstance(items, int):
qs = qs.order_by('-id')[:items]
for q in qs:
q.shortcode = create_shortcode(q)
print (q.id, " ", q.shortcode)
q.save()
new_codes += 1
return "# new codes created {id}".format(id = new_codes)
class URL(models.Model):
url = models.CharField(max_length = 220, )
shortcode = models.CharField(max_length = SHORTCODE_MAX, blank = True, unique = True)
updated = models.DateTimeField(auto_now = True)
timestamp = models.DateTimeField(auto_now_add = True)
active = models.BooleanField(default = True)
objects = UrlManager()
def save(self, *args, **kwargs):
if self.shortcode is None or self.shortcode == "":
self.shortcode = create_shortcode(self)
super(URL, self).save(*args, **kwargs)
def __str__(self):
return str(self.url)
def __unicode__(self):
return str(self.url)
# class Meta:
# ordering = '-id'
Can someone explain the the reason of error to me and how to solve it? I'm open to provide more informations IF required.
Solution 1:
Another way this error can occur is when you reload the module with the class in a Jupiter notebook.
Easy solution is to restart the kernel.
http://thomas-cokelaer.info/blog/2011/09/382/
Check out @Mike W's answer for more detail.
Solution 2:
You should call super
using the UrlManager
class as first argument not the URL
model. super
cannot called be with an unrelated class/type:
From the docs,
super(type[, object-or-type])
: Return a proxy object that delegates method calls to a parent or sibling class of type.
So you cannot do:
>>> class D:
... pass
...
>>> class C:
... def __init__(self):
... super(D, self).__init__()
...
>>> C()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __init__
TypeError: super(type, obj): obj must be an instance or subtype of type
You should do:
qs_main = super(UrlManager, self).all(*args, **kwargs)
Or in Python 3:
qs_main = super().all(*args, **kwargs)
Solution 3:
Elaborating in @Oğuz Şerbetci's answer, in python3 (not necessary only in Jupyter), when there is the need to reload a library, for example we have class Parent
and class Child
defined as
class Parent(object):
def __init__(self):
# do something
class Child(Parent):
def __init__(self):
super(Child, self).__init__(self)
then if you do this
import library.Child
reload(library)
Child()
you will get TypeError: super(type, obj): obj must be an instance or subtype of type
, the solution is just to re import the class after the reload
import library.Child
reload(library)
import library.Child
Child()
Solution 4:
For Jupyter only
You can get his issue in because reload
logic have some bugs (issue)
Here is a simple solution/workaround that works for me until issue is not fixed
- Add typo like
1001xx
at the bottom of the file which you call in the cell - Run your cell - you will see some exception, just skip it
- Remove typo which was added on step 1
- Run the cell
- Profit