Ich möchte ein ForeignKey
-Feld in einem Django-Modell einrichten, das manchmal auf eine andere Tabelle zeigt. Aber ich möchte, dass es in Ordnung ist, eine ID in dieses Feld einzufügen, die sich auf einen Eintrag in der anderen Tabelle bezieht, der möglicherweise nicht dort ist. Wenn also die Zeile in der anderen Tabelle vorhanden ist, möchte ich alle Vorteile der ForeignKey-Beziehung nutzen. Aber wenn nicht, würde ich das als eine Nummer behandeln lassen.
Ist das möglich? Ist das was generische Beziehungen sind?
Diese Frage wurde vor langer Zeit gestellt, aber für Neulinge gibt es jetzt eine eingebaute Möglichkeit, dies zu handhaben, indem Sie db_constraint = False auf ForeignKey setzen:
%Vor%oder wenn Sie NULL-Werte haben möchten und nicht referentielle Integrität erzwingen wollen:
%Vor%Wir verwenden dies in Fällen, in denen wir nicht garantieren können, dass die Beziehungen in der richtigen Reihenfolge erstellt werden.
BEARBEITEN: Link aktualisieren
Ich bin neu in Django, also tue ich es jetzt nicht, wenn es das bietet, was Sie wollen, out-of-the-box. Ich dachte an so etwas:
%Vor%Ich weiß nicht, ob Sie die contrib-Admin-App verwenden. Mit PositiveIntegerField anstelle von ForeignKey würde das Feld mit einem Textfeld auf der Admin-Site gerendert werden.
Das ist wahrscheinlich so einfach, wie einen ForeignKey zu deklarieren und die Spalte zu erstellen, ohne sie als FOREIGN KEY zu deklarieren. Auf diese Weise erhalten Sie o.obj_id, o.obj wird funktionieren, wenn das Objekt existiert, und - ich denke - eine Ausnahme auslösen, wenn Sie versuchen, ein Objekt zu laden, das nicht wirklich existiert (wahrscheinlich DoesNotExist
) .
Ich glaube jedoch nicht, dass Sie syncdb
für sich tun können. Ich fand syncdb
so einschränkend, dass es nutzlos ist, also umgehe ich es komplett und erstelle das Schema mit meinem eigenen Code. Sie können syncdb verwenden, um die Datenbank zu erstellen, und dann die Tabelle direkt ändern, z. ALTER TABLE tablename DROP CONSTRAINT fk_constraint_name
.
Sie verlieren natürlich auch ON DELETE CASCADE und alle referenziellen Integritätsprüfungen.
(Hinweis: Es könnte hilfreich sein, wenn Sie erklären, warum Sie dies möchten. Es könnte einen besseren Weg geben, sich dem zugrunde liegenden Problem zu nähern.)
Ist das möglich?
Nicht nur mit ForeignKey, weil Sie die Spaltenwerte mit zwei verschiedenen Bedeutungen überladen, ohne eine zuverlässige Unterscheidung zu finden. (Was würde beispielsweise passieren, wenn ein neuer Eintrag in der Zieltabelle mit einem Primärschlüssel erstellt wird, der mit alten Einträgen in der Referenztabelle übereinstimmt? Was würde mit diesen alten Referenzeinträgen geschehen, wenn der neue Zieleintrag gelöscht wird?)
Die übliche Ad-hoc-Lösung für dieses Problem besteht darin, neben dem Fremdschlüssel eine "type" - oder "tag" -Spalte zu definieren, um die verschiedenen Bedeutungen zu unterscheiden (siehe unten).
Ist das was generische Beziehungen sind?
Ja, teilweise.
GenericForeignKey ist nur ein Django-Hilfsprogramm für das obige Muster; es paart einen Fremdschlüssel mit einem Typ-Tag, das angibt, auf welche Tabelle / Modell es verweist (mit dem zugeordneten ContentType des Modells; siehe contenttypes )
Beispiel:
%Vor% Damit können Sie other
wie einen ForeignKey verwenden, um auf Instanzen Ihres anderen Modells zu verweisen. (Im Hintergrund erhält und setzt GenericForeignKey other_type
und other_id
für Sie.)
Um eine Zahl darzustellen, die keine Referenz ist, würden Sie other_type
auf None setzen und einfach other_id
direkt verwenden. In diesem Fall gibt der Zugriff auf other
immer None zurück, anstatt DoesNotExist
zu erhöhen (oder ein unbeabsichtigtes Objekt aufgrund einer ID-Kollision zurückzugeben).
Tags und Links python django foreign-keys django-models