Trabajo en una pequeña aplicación de Django y aparece un error que me dice 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 models.py 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'¿Alguien puede explicarme el motivo del error y cómo solucionarlo? Estoy abierto a proporcionar más información si es necesario.
Debe llamar a super usando la clase UrlManager como primer argumento, no el modelo de URL . super no puede llamarse con una clase/tipo no relacionado :
De los documentos,
super(type[, object-or-type]): devuelve un objeto proxy que delega llamadas de método a una clase padre o hermana de tipo.
Entonces no puedes hacer:
>>> 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 typeDeberías hacer:
qs_main = super(UrlManager, self).all(*args, **kwargs)O en Python 3:
qs_main = super().all(*args, **kwargs)Otra forma interesante es si una combinación de ramas 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 a 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 me sucedió a mí, cuando no estaba prestando suficiente atención a la fusión de dos ramas. Mis pruebas fallaron con el mensaje de error descrito en la pregunta, así que pensé en dejar mis hallazgos aquí, aunque no responde exactamente a la pregunta específica.
Otra forma en que puede ocurrir este error es cuando recarga el módulo con la clase en un cuaderno de Júpiter.
La solución fácil es reiniciar el kernel.
http://thomas-cokelaer.info/blog/2011/09/382/
Consulte la respuesta de @Mike W para obtener más detalles.
Elaborando en la respuesta de @ Oğuz Şerbetci, en python3 (no es necesario solo en Jupyter), cuando existe la necesidad de recargar una biblioteca, por ejemplo, tenemos class Parent y class Child definidas como
class Parent(object): def __init__(self): # do something class Child(Parent): def __init__(self): super(Child, self).__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()Solo para Jupyter Puede obtener su problema porque la lógica de reload tiene algunos errores ( problema )
Aquí hay una solución / solución alternativa simple que funciona para mí hasta que el problema no se solucione
1001xx en la parte inferior del archivo que llama en la celdaLa mejor solución que he encontrado para este problema solo está disponible usando python 3. Entonces no necesita especificar los argumentos de "super", entonces ya no tendrá el error al escribir su clase de esta manera:
class D: pass class C(D): def __init__(self): super().__init__()# no arguments given to super()Este error también aparece cuando simplemente no crea una instancia de la clase secundaria e intenta llamar a un método en una clase en sí, como en:
class Parent: def method(): pass class Child(Parent): def method(): super().method() P = Parent() C = Child C.method()