Ik werk aan een kleine Django
-app en krijg een foutmelding die me vertelt: super(type, obj): obj must be an instance or subtype of type
. Ik haal het uit het bestand views.py
nadat ik de functie get_object_or_404
heb geïntroduceerd. Het bestand views.py
hieronder,
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()
de volledige foutmelding staat hier,
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
De line 18
in de models.py
is qs_main = super(URL, self).all(*args, **kwargs)
en het bestand models.py
is hier,
# 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'
Kan iemand mij de reden van de fout uitleggen en hoe ik deze kan oplossen? Ik sta open om meer informatie te verstrekken ALS dat nodig is.
Antwoord 1, autoriteit 100%
Een andere manier waarop deze fout kan optreden, is wanneer u de module opnieuw laadt met de klasse in een Jupiter-notebook.
Eenvoudige oplossing is om de kernel opnieuw te starten.
http://thomas-cokelaer.info/blog/2011/09/382 /
Bekijk het antwoordvan @Mike W voor meer informatie.
Antwoord 2, autoriteit 24%
Je moet super
aanroepen met de klasse UrlManager
als eerste argument, niet het URL
-model. super
kan niet worden aangeroepen met een niet-verwanteklasse/type:
Uit de documenten,
super(type[, object-or-type])
:
Retourneer een proxy-object dat methodeaanroepen delegeert aan een ouder of
broer/zus klasse van type.
Dus u kuntniet doen:
>>> 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
Je moet doen:
qs_main = super(UrlManager, self).all(*args, **kwargs)
Of in Python 3:
qs_main = super().all(*args, **kwargs)
Antwoord 3, autoriteit 18%
Uitwerkend in het antwoord van @Oğuz Şerbetci, in python3 (niet alleen nodig in Jupyter), wanneer het nodig is om een bibliotheek opnieuw te laden, we hebben bijvoorbeeld class Parent
en class Child
gedefinieerd als
class Parent(object):
def __init__(self):
# do something
class Child(Parent):
def __init__(self):
super(Child, self).__init__(self)
als je dit doet
import library.Child
reload(library)
Child()
u krijgt TypeError: super(type, obj): obj must be an instance or subtype of type
, de oplossing is gewoon om de klasse opnieuw te importeren na het opnieuw laden
import library.Child
reload(library)
import library.Child
Child()
Antwoord 4, autoriteit 6%
Alleen voor Jupyter
Je kunt zijn probleem binnenhalen omdat de logica van reload
enkele bugs bevat (probleem)
Hier is een eenvoudige oplossing/workaround die voor mij werkt totdat het probleem niet is opgelost
- Voeg typefout toe zoals
1001xx
onderaan het bestand dat je in de cel aanroept - Laat je cel lopen – je zult een uitzondering zien, sla deze gewoon over
- Verwijder typfout die bij stap 1 is toegevoegd
- Voer de cel uit
- Winst
Antwoord 5, autoriteit 3%
Een andere interessante manier is als een samenvoeging van branches de klasse heeft gedupliceerd, zodat je in het bestand twee definities voor dezelfde naam hebt, bijvoorbeeld
class A(Foo):
def __init__(self):
super(A, self).__init__()
#...
class A(Foo):
def __init__(self):
super(A, self).__init__()
#...
Als u probeert een instantie te maken van een statische verwijzing naar de eerste definitie van A, zodra deze probeert super
aan te roepen, binnen de __init__
methode, A
verwijst naar de tweede definitie van A
, aangezien deze is overschreven. De oplossing – natuurlijk – is om de dubbele definitie van de klasse te verwijderen, zodat deze niet wordt overschreven.
Dit lijkt misschien iets dat nooit zou gebeuren, maar het overkwam me gewoon, toen ik niet goed genoeg aandacht besteedde aan het samenvoegen van twee branches. Mijn tests mislukten met de foutmelding die in de vraag wordt beschreven, dus ik dacht ik laat mijn bevindingen hier achter, ook al beantwoordt het niet precies de specifieke vraag.
Antwoord 6, autoriteit 2%
De beste oplossing die ik voor dit probleem heb gevonden, is alleen beschikbaar met python 3. Je hoeft dan de argumenten van “super” niet op te geven, dan heb je niet meer de fout om je klasse op deze manier te schrijven :
class D:
pass
class C(D):
def __init__(self):
super().__init__()# no arguments given to super()
Antwoord 7
Deze fout verschijnt ook wanneer u eenvoudigweg geen onderliggende klasse instantiëert
, en probeer een methode op een klasse zelf aan te roepen, zoals in :
class Parent:
def method():
pass
class Child(Parent):
def method():
super().method()
P = Parent()
C = Child
C.method()