Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

super(type, obj): obj must be an instance or subtype of type

Tags:

python

django

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.

like image 307
Heisenberg Avatar asked May 03 '17 05:05

Heisenberg


2 Answers

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.

like image 82
Oğuz Şerbetci Avatar answered Sep 23 '22 12:09

Oğuz Şerbetci


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) 
like image 43
Moses Koledoye Avatar answered Sep 22 '22 12:09

Moses Koledoye