super (tipo, obj): obj debe ser una instancia o subtipo de tipo

Trabajo en una pequeña aplicación de Django y recibo un error que me dice que super(type, obj): obj must be an instance or subtype of type . Lo obtengo del archivo views.py después de introducir la función get_object_or_404 . El archivo views.py proporcionado a continuación,

 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() 

el mensaje de error completo está aquí,

 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 

La line 18 en los qs_main = super(URL, self).all(*args, **kwargs) es qs_main = super(URL, self).all(*args, **kwargs) y el archivo models.py está aquí,

 # 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' 

¿Puede alguien explicarme la razón del error y cómo resolverlo? Estoy abierto a proporcionar más información si es necesario.

Debe llamar a super utilizando la clase UrlManager como primer argumento, no como modelo de URL . super no puede ser llamado con una clase / tipo no relacionado :

De los documentos,

super(type[, object-or-type]) : devuelve un objeto proxy que delega las llamadas de método a una clase de tipo padre o hermana.

Así que no puedes hacer:

 >>> class D: ... pass ... >>> class C: ... def __init__(self): ... super(D, self).__init__() ... >>> C() Traceback (most recent call last): File "", line 1, in  File "", line 3, in __init__ TypeError: super(type, obj): obj must be an instance or subtype of type 

Deberías hacer:

 qs_main = super(UrlManager, self).all(*args, **kwargs) 

O en Python 3:

 qs_main = super().all(*args, **kwargs) 

Otra forma en que puede ocurrir este error es cuando vuelve a cargar el módulo con la clase en un cuaderno de Jupiter.

http://thomas-cokelaer.info/blog/2011/09/382/

Elaboración en la respuesta de @ Oğuz Şerbetci, en python3 (no es necesario solo en Jupyter), cuando existe la necesidad de volver a cargar una biblioteca, por ejemplo, tenemos la class Parent y la class Child definidas como

 class Parent(object): def __init__(self): # do something class Child(Parent): def __init__(self): super(self,Child).__init__(self) 

entonces si haces esto

 import library.Child reload(library) Child() 

obtendrá TypeError: super(type, obj): obj must be an instance or subtype of type , la solución es simplemente volver a importar la clase después de la recarga

 import library.Child reload(library) import library.Child Child() 

Otra forma interesante es si una combinación de twigs ha duplicado la clase, de modo que en el archivo tenga dos definiciones para el mismo nombre, por ejemplo

 class A(Foo): def __init__(self): super(A, self).__init__() #... class A(Foo): def __init__(self): super(A, self).__init__() #... 

Si intenta crear una instancia a partir de una referencia estática a la primera definición de A, una vez que intente llamar super , dentro del método __init__ , A se referirá a la segunda definición de A , ya que se ha sobrescrito. La solución, por supuesto, es eliminar la definición duplicada de la clase, para que no se sobrescriba.

Esto puede parecer algo que nunca sucedería, pero simplemente me pasó a mí, cuando no estaba prestando suficiente atención a la fusión de dos sucursales. Mis pruebas fallaron con el mensaje de error descrito en la pregunta, así que pensé que debería dejar mis resultados aquí, aunque no responda exactamente a la pregunta específica.