Ich definiere gerade meine Django-Modelle und habe festgestellt, dass es OneToManyField
in den Modellfeldtypen keine gibt . Ich bin mir sicher, dass es einen Weg gibt, also bin ich mir nicht sicher, was mir fehlt. Ich habe im Wesentlichen so etwas:
class Dude(models.Model):
numbers = models.OneToManyField('PhoneNumber')
class PhoneNumber(models.Model):
number = models.CharField()
In diesem Fall kann jedes Dude
mehrere PhoneNumber
s haben, aber die Beziehung sollte unidirektional sein, da ich nicht wissen muss PhoneNumber
, Dude
wem es per se gehört, da ich möglicherweise viele verschiedene Objekte habe, die PhoneNumber
Instanzen besitzen, wie z. B. ein Business
for Beispiel:
class Business(models.Model):
numbers = models.OneToManyField('PhoneNumber')
Was würde ich OneToManyField
im Modell ersetzen (was nicht existiert), um diese Art von Beziehung darzustellen? Ich komme aus Hibernate / JPA, wo es so einfach war, eine Eins-zu-Viele-Beziehung zu erklären:
@OneToMany
private List<PhoneNumber> phoneNumbers;
Wie kann ich das in Django ausdrücken?
quelle
dude = models.ForeignKey(Dude, related_name='numbers')
, können Sie dannsome_dude_object.numbers.all()
alle zugehörigen Nummern abrufen (wenn Sie keinen "verwandten_Namen" angeben, wird standardmäßig "number_set" verwendet).In Django heißt eine Eins-zu-Viele-Beziehung ForeignKey. Es funktioniert jedoch nur in eine Richtung, sodass Sie kein
number
KlassenattributDude
benötigenViele Modelle können eine haben ,
ForeignKey
um ein anderes Modell, so dass es gültig wäre , ein zweites Attribut haben ,PhoneNumber
so dassSie können auf das
PhoneNumber
s für einDude
Objektd
mit zugreifend.phonenumber_set.objects.all()
und dann für einBusiness
Objekt ähnlich vorgehen.quelle
ForeignKey
dass "eins zu eins" bedeutete. Mit Ihrem obigen Beispiel sollte ich eine habenDude
, die vielePhoneNumbers
richtig hat?ForeignKey
ist nur eins zu eins, wenn Sie angebenForeignKey(Dude, unique=True)
, so dass Sie mit dem obigen Code einDude
mit mehrerenPhoneNumber
s erhalten.PhoneNumber
. Jetzt macht es langsam Sinn.ForeignKey
ist im Wesentlichen viele zu eins, also müssen Sie es rückwärts machen, um eins zu viele zu bekommen :)phonenumber_set
? Ich sehe es nirgendwo definiert. Ist es der Name des Modells, der in Kleinbuchstaben mit "_set" versehen ist?Um es klarer zu machen - es gibt kein OneToMany in Django, nur ManyToOne - das ist der oben beschriebene Foreignkey. Sie können die OneToMany-Beziehung mit Foreignkey beschreiben, aber das ist sehr unaussprechlich.
Ein guter Artikel dazu: https://amir.rachum.com/blog/2013/06/15/a-case-for-a-onetomany-relationship-in-django/
quelle
Sie können entweder Fremdschlüssel auf vielen Seiten der
OneToMany
Beziehung (dhManyToOne
Beziehung) oderManyToMany
(auf jeder Seite) mit eindeutiger Einschränkung verwenden.quelle
django
ist klug genug. Eigentlich müssen wir keinoneToMany
Feld definieren . Es wird automatisch vondjango
für Sie generiert :-). Wir müssen nurforeignKey
in der zugehörigen Tabelle definieren . Mit anderen Worten, wir müssen dieManyToOne
Beziehung nur mit definierenforeignKey
.wenn wir die Liste der Räder eines bestimmten Autos erhalten wollen. Wir werden
python's
automatisch generierte Objekte verwendenwheel_set
. Für das Auto werdenc
Sie verwendenc.wheel_set.all()
quelle
Die Antwort von Rolling Stone ist zwar gut, unkompliziert und funktional, aber ich denke, es gibt zwei Dinge, die es nicht löst.
Führen Sie das Framework für Inhaltstypen ein , das einige Objekte verfügbar macht, mit denen wir einen "generischen Fremdschlüssel" für das PhoneNumber-Modell erstellen können. Dann können wir die umgekehrte Beziehung für Dude und Business definieren
Weitere Informationen finden Sie in den Dokumenten. In diesem Artikel finden Sie möglicherweise ein kurzes Tutorial.
Hier ist auch ein Artikel , der gegen die Verwendung von generischen FKs spricht.
quelle
Wenn das "viele" -Modell die Erstellung eines Modells an sich nicht rechtfertigt (hier nicht der Fall, aber es könnte anderen Menschen zugute kommen), besteht eine andere Alternative darin, sich über das Django Contrib-Paket auf bestimmte PostgreSQL-Datentypen zu verlassen
Postgres kann mit Array- oder JSON- Datentypen umgehen , und dies kann eine gute Problemumgehung für One-to-Many sein, wenn die Many -ies nur an eine einzelne Entität des einen gebunden werden können .
Mit Postgres können Sie auf einzelne Elemente des Arrays zugreifen. Dies bedeutet, dass Abfragen sehr schnell durchgeführt werden können und Overheads auf Anwendungsebene vermieden werden. Und natürlich implementiert Django eine coole API , um diese Funktion zu nutzen.
Es hat offensichtlich den Nachteil, dass es nicht für andere Datenbank-Backends portierbar ist, aber ich denke, es ist immer noch erwähnenswert.
Hoffe, es kann einigen Leuten helfen, nach Ideen zu suchen.
quelle
Zunächst machen wir eine Tour:
01) Eins-zu-Viele-Beziehung:
NB: Django bietet keine OneToMany-Beziehung. Daher können wir in Django keine obere Methode verwenden. Aber wir müssen in ein relationales Modell konvertieren. Also was können wir tun? In dieser Situation müssen wir das relationale Modell in ein umgekehrtes relationales Modell umwandeln.
Hier:
relationales Modell = OneToMany
Also, umgekehrtes relationales Modell = ManyToOne
NB: Django unterstützt die ManyToOne-Beziehung und in Django wird ManyToOne von ForeignKey vertreten.
02) Viele-zu-Eins-Beziehung:
NB: EINFACH DENKEN !!
quelle