Seite 1 von 2
Zwei unmanaged models miteinander "joinen"?
Verfasst: Freitag 8. November 2024, 17:45
von gospat83
Hallo zusammen,
ich bin gerade dabei mein erstes Django Projekt aufzusetzen. Ich kann leider nicht alle Daten in Django selbst generieren lassen, sondern benötige auch bereits bestehende Daten aus unserem ERP System. Deshalb habe ich über inspectdb zwei Views als Model erzeugen lassen. Meine models.py sieht wie folgt aus:
Code: Alles auswählen
from django.db import models
class PentaProjectMasterData(models.Model):
project = models.CharField(max_length=10, blank=False, null=False)
project_name = models.CharField(max_length=8000, blank=True, null=True)
cost_bearer = models.CharField(max_length=6, blank=False, null=False, primary_key=True)
class Meta:
managed = False # Created from a view. Don't remove.
db_table = 'penta_project_master_data'
class PentaSystem(models.Model):
system = models.CharField(max_length=4, blank=False, null=False, primary_key=True)
system_name = models.CharField(max_length=30, blank=True, null=True)
cost_bearer = models.CharField(max_length=6, blank=False, null=False)
class Meta:
managed = False # Created from a view. Don't remove.
db_table = 'penta_system'
Das Feld cost_bearer aus dem PentaProjectMasterData soll der Fremdschlüssel im PentaSystem Model sein. Wie mache ich das, bzw. ist das überhaupt möglich?
Viele Grüße
gospat
Re: Zwei unmanaged models miteinander "joinen"?
Verfasst: Freitag 8. November 2024, 18:36
von sparrow
Das sollte einfach ein ForeignKey sein.
Re: Zwei unmanaged models miteinander "joinen"?
Verfasst: Samstag 9. November 2024, 13:46
von gospat83
Danke, das stimmt. Ich habe lange gebraucht um zu verstehen wie genau ich den FK setzen muss (da automatisch von Django z.B. "_id" gesetzt wird etc.).
Jetzt habe ich ein anderes Problem. Im Admin Panel versuche ich eine neue
ResponsiblePerson anzulegen. Aber bei den Feldern
Cost bearer und
System bekomme ich im Dropdown a) viel zu viele Werte angezeigt und b) sind diese irgendwie verkettet.
So sieht meine models.py aus:
Code: Alles auswählen
from django.db import models
class ProjectMasterData(models.Model):
project = models.CharField(max_length=10, blank=True, null=True)
project_name = models.CharField(max_length=8000, blank=True, null=True)
cost_bearer_id = models.CharField(max_length=6, blank=False, null=False)
system_id = models.CharField(max_length=4, blank=False, null=False)
system_name = models.CharField(max_length=30, blank=True, null=True)
key_id = models.CharField(max_length=10, primary_key=True)
class Meta:
managed = False # Created from a view. Don't remove.
db_table = 'project_master_data'
def __str__(self):
return f"{self.cost_bearer_id} | {self.system_id}"
class ResponsiblePerson(models.Model):
name = models.CharField(max_length=100, blank=False, null=False)
department = models.CharField(max_length=100, blank=False, null=False)
cost_bearer = models.ForeignKey(ProjectMasterData, on_delete=models.CASCADE, related_name='cost_bearer', db_constraint=False)
system = models.ForeignKey(ProjectMasterData, on_delete=models.CASCADE, related_name='system', db_constraint=False)
def __str__(self):
return f"{self.department} | {self.name} | {self.cost_bearer} | {self.system}"
Wenn ich versuche einen neuen Eintrag im Admin Panel zu erzeugen, sieht es so aus, dass sowohl beim Dropdown für Cost bearer als auch für System z.B. folgendes steht:
313759 | 0310. Der Wert für Cost bearer ist aber nur "313759" und "0310" ist eigentlich der Wert für system. Was mache ich falsch bzw. wie bekomme ich das geändert?
Re: Zwei unmanaged models miteinander "joinen"?
Verfasst: Samstag 9. November 2024, 16:48
von sparrow
Ich verstehe leider die Relation nicht. Und du scheinst ein Problem mit dem Verständnis von ForeignKeys zu haben.
Rechnungen sind immer ein gutes Beispiel.
Es gibt eine Tabelle Rechnung.
Und es gibt eine Tabelle RechnungPositionen.
Rechnung hat irgend eine Spalte, die eine ID enthält. RechnungPosition hat eine Spalte mit einem Fremdschlüssel auf auf ID in Rechnung. Denn Rechnung 1 : n RechnungPosition.
Und wie ergibt so eine Relation aus deinen Daten?
Re: Zwei unmanaged models miteinander "joinen"?
Verfasst: Samstag 9. November 2024, 16:56
von __blackjack__
@gospat83: Da steht halt das was die `ProjectMasterData.__str__()`-Methode von dem Objekt liefert. Wenn da was anderes stehen soll, muss der Code dort anders aussehen.
Re: Zwei unmanaged models miteinander "joinen"?
Verfasst: Samstag 9. November 2024, 18:21
von gospat83
Ich verstehe leider nicht ganz wie ich das Ganze in Django umsetzen muss. Mal angenommen ich habe folgendes DB-Modell.
Tabelle Projekt
-------------------------
Projektnummer
Projektbezeichnung
Tabelle Baugruppe
------------------------------
Baugruppennummer
Baugruppenbezeichnung
FK Projektnummer aus Tabelle Projekt
Tabelle Verantwortlicher
--------------------------------------
Name
Abteilung
FK Baugruppennummer aus Tabelle Baugruppe
FK Projektnummer aus der Tabelle Projekt
Eine Baugruppe bezieht sich immer auf eine Projektnummer. Der Verantwortliche bezieht sich immer auf die Kombination aus Baugruppennummer und Projektnummer.
Ich hoffe es ist klar was ich erreichen möchte. Wie müsste dafür meine models.py aussehen? Ich verstehe noch nicht so gant was Django da automatisch alles im Hintergrund macht, z.B. mit dem ergänzen der "_id" beimForeign Key. Vermutlich scheitert das Ganze nur an Kleinigkeiten.
Re: Zwei unmanaged models miteinander "joinen"?
Verfasst: Samstag 9. November 2024, 18:29
von __blackjack__
@gospat83: Das sieht doppelt verbunden aus. Wenn man vom Verantwortlichen zum Projekt kommt, steht ja im Grunde auch die Baugruppe fest. Oder kann der Verantwortliche eine andere Baugruppe haben als das Projekt?
Re: Zwei unmanaged models miteinander "joinen"?
Verfasst: Samstag 9. November 2024, 18:35
von gospat83
Ich versuche es mal anhand eines Beispiels.
Baugruppe 0100 Projekt A Verantwortlicher Klaus
Baugruppe 0100 Projekt B Verantwortlicher Michael
Die Baugruppe kann es also von der Bezeichnung her in mehreren Projekten geben, aber sie hat dabei immer die selbe Baugruppennummer. Die Baugruppenbezeichnung kann sich jedoch unterscheiden.
Der Verantwortliche ist also nicht automatisch komplett für z.B. alle 0100 Baugruppen verantwortlich, sondern evtl. nur für bestimmte Projekte.
Erklärt es das?
Re: Zwei unmanaged models miteinander "joinen"?
Verfasst: Samstag 9. November 2024, 18:43
von __blackjack__
@gospat83: Wenn eine Baugruppe in mehr als einem Projekt verwendet werden kann, dann kann der Fremdschlüssel nicht in der Baugruppe liegen. Da kann man pro Baugruppe ja nur *einen* Wert für ein Projekt hinterlegen.
Re: Zwei unmanaged models miteinander "joinen"?
Verfasst: Samstag 9. November 2024, 18:45
von sparrow
@gospat83: Deine Erklärung passt nicht zu dem, was du da in der Datenbank abbilden möchtest. Kann ein Projekt mehr als eine Baugruppe haben?
Re: Zwei unmanaged models miteinander "joinen"?
Verfasst: Samstag 9. November 2024, 19:23
von gospat83
Ja, ein Projekt hat auf jeden Fall mehr als eine Baugruppe.
Re: Zwei unmanaged models miteinander "joinen"?
Verfasst: Samstag 9. November 2024, 19:31
von gospat83
Ich versuche mal die gewünschten Beziehungen zu skizzieren anhand von Beispielinhalten.
Tabelle Projekt
---------------
Projektnummer
1
2
3
Tabelle Baugruppe
-----------------
Baugruppennummer Baugruppenbezeichnung Projekt
0100 bez_a 1
0100 bez_b 2
0400 test 3
Tabelle Verantwortlicher
------------------------
Name Abteilung Baugruppennummer Projekt
Willy IT 0100 1
Peter Einkauf 0100 2
Klasu Controlling 0400 3
Re: Zwei unmanaged models miteinander "joinen"?
Verfasst: Samstag 9. November 2024, 20:24
von sparrow
Dann hat Projekt eine n:m Beziehung zu den Baugruppen.
Deine Tabellen müssten also so aussehen, wenn du die nicht mit dem Django verwalten lassen möchtest.
== sind die Tabellen. Darunter die Felder. Fremdschlüssel mit dem Relation.zielfeld.
Code: Alles auswählen
== Abteilung
id
name
== MITARBEITER
id
name
abteilung (Fremschlüssel Abteilung.id)
== BAUGRUPPE
id
bezeichung
== PROJEKT
id
bezeichnung
== BAUGRUPPE_ZU_PROJEKT
id
baugruppe (Fremschlüssel Baugruppe.id)
projekt (Fremschlüssel Projekt.id)
verantwortlicher (Fremdschlüssel Mitarbeiter.id)
baugruppenbezeichnung_im_projekt
Das müsste die entsprechend Normalisierung sein.
Re: Zwei unmanaged models miteinander "joinen"?
Verfasst: Samstag 9. November 2024, 22:00
von gospat83
Super, vielen Dank für deine Mühe.
Re: Zwei unmanaged models miteinander "joinen"?
Verfasst: Samstag 9. November 2024, 23:25
von sparrow
@gospat83: Es lohnt auch noch einmal der Einstieg in die Dokumentation. Man kann eine Datenbank, die bereits existiert, problemlos mit Django verwenden. Es wird gar nichts daran verändert, wenn man die entsprechenden Optionen setzt. Weder werden Spalten angelegt noch müssen Spalten bestimmte Namen haben. Auch Spalten mit Fremschlüsseln _müssen_ nicht auf _id enden. Das tun sie, wenn Django sie selbst anlegt - man kann den Namen der Spalte aber auch angeben.
Wichtig ist, dass man auch beachtet, dass man trotzdem die Spalte mit dem Primärschlüssel entsprechend gleich mit der Datenbank angibt. Wenn man keine solche Spalte deklariert, wird sie automatisch in der Datenbank angelegt.
Re: Zwei unmanaged models miteinander "joinen"?
Verfasst: Mittwoch 13. November 2024, 19:38
von gospat83
@sparrow: Ich muss hier nochal nachhaken, anscheinend bin ich zu blöd...
Ich habe jetzt ein unmanaged model aus einer SQL Server DB. Die DB-Tabelle heißt Projekt. In dieser Tabelle sind zwei Felder:
1. PSP_IDENT
2. Kostentraeger
Der PSP_IDENT ist der PK der Tabelle.
Nun habe ich eine zweite Tabelle direkt in Django angelegt, sprich es handelt sich um ein managed model. Diese Tabelle heißt z.B. Verantwortlicher. Diese Tabelle soll jetzt den PSP_IDENT aus der Projekt Tabelle als FK nutzen. Wie genau - und zwar ganz genau - muss mein Model dafür aussehen? Django macht aus PSP_IDENT ja immer automatisch PSP_IDENT_ID und so heißt mein DB-Feld nunmal nicht. Wie bekomme ich es hin, dass das Feld einfach seinen ursprünglichen Namen behält und ich es nutzen kann. Ich würde normalerweise ja einfach das in der Verantwortlicher Tabelle schreiben:
psp_ident = models.ForeignKey(Projekt, on_delete.models.CASCADE)
Es wäre toll, wenn mir mal jemand das genaue Model für meine Tabelle erstellen könnte, ich drehe mich hier irgendwie im Kreis.
Muss der vordere Part eigentlich immer genau dem Namen aus der anderen Tabelle entsprechen?
Viele Grüße
gospat
Re: Zwei unmanaged models miteinander "joinen"?
Verfasst: Mittwoch 13. November 2024, 19:48
von sparrow
Aber wenn Django die Tabelle managen soll, dann ist es doch ok, wenn das Feld psp_ident_id heißt. Weil du dein Feld so benannt hast.
Richtiger (weil zu lesen) wäre:
Code: Alles auswählen
projekt = models.ForeignKey(Projekt, on_delete.models.CASCADE)
Dann wird ein Feld "projekt_id" in der "Verantwortlicher" angelegt. Und das ist ja auch korrekt.
Re: Zwei unmanaged models miteinander "joinen"?
Verfasst: Mittwoch 13. November 2024, 20:28
von gospat83
Sorry, aber ich blicke da nicht durch. Die Projekt Tabelle hat doch den PSP_Ident als PK. Den möchte ich doch auch nutzen. Eine Projekt_ID gibt es doch gar nicht oder legt Django auch bei unmanaged Models selber Spalten an?
Re: Zwei unmanaged models miteinander "joinen"?
Verfasst: Mittwoch 13. November 2024, 22:16
von sparrow
_Du_ hast doch geschrieben, dass Django ein _id anhängt. Das tut es aber nur, wenn es ein Fremschlüsselfeld ist. Und ein vernünftiger Name für das Feld in "Verantwortlicher" ist nun mal nicht psp_ident sondern projekt. Weil mit psp_ident kein Mensch etwas anfangen kann.
Und wenn du "projekt" in "Verantwortlicher" wie von mir gezeigt als Fremschlüssel anlegst, dann heißt das Feld im Model projekt und in der Datenbank wird das Feld "projekt_id" angelegt. Das ist sinnvoll. Erklärt wird das wie immer in der
Dokumentation. Das möchte man eigentlich auch nicht ändern, weil das auch auf Database-Level sehr angenehm zu lesen ist. Denn auch dort vergibt man vernünftige Namen.
Und wenn der Primary-Key in dem unmanaged Model für "Projekt" korrekt gesetzt ist (was er sein sollte, denn dein Model sollte ja der Realität der Datenbank entsprechen), dann ist es völlig egal, wie dort das Feld in der Datenbank heißt. Anhand der Definition im Model weiß Django, welches Feld verwendet werden muss (nämlich eben der PK).
Dein nicht so schön benanntes Feld PSP_IDENT ist der PK von Projekt. Der hat gar nichts mit dem Feldnamen des Fremdschlüssels in Verantwortlicher zu tun. Bis auf, dass es das Ziel des Fremdschlüssels ist. Und das ist es automatisch, wenn es korrekt als PrimaryKey im Model von "Projekt" definiert ist.
Re: Zwei unmanaged models miteinander "joinen"?
Verfasst: Donnerstag 14. November 2024, 09:27
von gospat83
Ok, jetzt ist der Groschen gefallen denke ich. Danke für deine Geduld, aber wenn man da einen Knoten im Kopf hat, ist es manchmal schwierig. Ich dachte immer, dass die Namen von PK und FK übereinstimmen müssen.
Jetzt habe ich nur noch eine weitere Frage zu dem Thema, auch wenn sie für dich wahrscheinlich glasklar ist. Wenn ich jetzt wiederum den PK der Verantwortlicher Tabelle (managed) in einer weiteren unmanaged Tabelle als FK nutzen möchte, wie muss diese unmanaged Tabelle dann aussehen? Der PK lautet ja dann verantwortlicher_id. Das heißt für mich, dass ich auch ein entsprechendes Feld mit dem Namen in meiner DB-Tabelle für das unmanaged model anlegen muss, richtig?