Das Instanziieren des Django-Modells löst TypeError aus: isinstance () Argument 2 muss eine Klasse, ein Typ oder ein Tupel von Klassen und Typen sein

8

Ich habe eine bestehende, funktionierende Django-Anwendung, die seit einigen Monaten im DEBUG-Modus läuft. Wenn ich die Site für die Ausführung im Produktionsmodus ändere, erhalte ich die folgenden Ausnahme-E-Mails, die an mich gesendet werden, wenn ich auf eine bestimmte Ansicht stoße, die versucht, ein neues Referenzmodellobjekt zu erstellen.

%Vor%

Wie Sie sehen, löst nur das Versuch, ein Referral-Modellobjekt zu instanziieren, diese Ausnahme aus. Hier ist das Modell in Frage:

%Vor%

Ist das ein Fehler in Django oder mache ich unwissentlich etwas, was ich nicht tun sollte? Irgendwelche Vorschläge für Korrekturen oder Workarounds?

    
Derek Edwards 17.01.2013, 19:24
quelle

2 Antworten

13

UPDATE (mit Lösung unten)

Ich habe mich mit dem Django-Modellcode beschäftigt und es scheint, dass es einen Fehler gibt, der eine Race Condition verursacht, wenn "app.model" -basierte IDs für das entsprechende Feld in einem ForeignKey verwendet werden. Wenn die Anwendung im Produktionsmodus im Gegensatz zu DEBUG ausgeführt wird, versucht die ForeignKey.get_default-Methode, auf die in der obigen Ausnahme verwiesen wird, zu überprüfen, ob der angegebene Standardwert eine Instanz des verwandten Felds (self.rel.to) ist:

%Vor%

Wenn ein ForeignKey mit einem stringbasierten verwandten Feld initialisiert wird, wird self.rel.to auf den stringbasierten Bezeichner gesetzt. Es gibt eine separate Funktion in related.py namens add_lazy_relation, die unter normalen Umständen versucht, diese zeichenfolgenbasierte ID in eine Modellklassenreferenz zu konvertieren. Da Modelle faul geladen werden, ist es möglich, dass diese Konvertierung verschoben werden kann, bis der AppCache vollständig geladen ist.

Wenn also get_default für eine String-basierte ForeignKey-Beziehung aufgerufen wird, bevor AppCache vollständig gefüllt ist, kann eine TypeError-Ausnahme ausgelöst werden. Offensichtlich reichte es aus, meine Anwendung in den Produktionsmodus zu versetzen, um das Timing des Modellcachings zu verschieben, bei dem dieser Fehler für mich auftrat.

LÖSUNG

Es scheint, dass dies wirklich ein Fehler in Django ist, aber hier ist, wie man es umgehen kann, wenn Sie jemals auf dieses Problem stoßen. Fügen Sie das folgende Code-Snippet unmittelbar vor der Instanziierung eines problematischen Modells hinzu:

%Vor%

Dies überprüft das geladene Flag im AppCache, um zu ermitteln, ob der Cache vollständig gefüllt ist. Wenn dies nicht der Fall ist, werden wir den Cache zwingen, jetzt vollständig zu füllen. Und das Problem wird gelöst.

    
Derek Edwards 18.01.2013, 00:06
quelle
1

Eine andere Ursache:

Stellen Sie sicher, dass sich alle Fremdschlüssel in denselben Referenzmodellen in derselben Anwendung (Anwendungsbezeichnung) befinden. Ich schlug meinen Kopf für eine Weile an die Wand.

%Vor%     
keithhackbarth 04.02.2013 20:19
quelle

Tags und Links