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.
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With