Django: Wie zwei Models elegant kombinieren?

25/03/2009 - 10:12 von Michael Ziegler | Report spam
Hallo NG,

ich muss hier(tm) Daten zu im Betrieb eingesetzten Chemikalien
speichern, von denen einige Felder allgemein gültig sind (Handelsname,
physikalische Daten), andere dagegen sind standortabhàngig (Lieferant,
Preis etc). Ich habe daher den Datensatz aufgeteilt in zwei Models.
Diese haben keine gemeinsamen Felder und ich greife nur über das
standortbezogene Model auf die Daten zu, daher ist auch in jedem Falle
klar um welchen Standort es geht und eine eindeutige Zuordnung der
Felder zu den Models ist möglich.

Ich suche jetzt nach einer Möglichkeit zu verhindern dass ich diesen
Umstand jeder View die diese Daten nutzen soll einzeln beibringen muss,
zumal das nicht die einzige App ist in der ich dieses Problem habe. Dazu
hab ich mich mal in Vererbung von Models eingelesen und das sieht auch
recht vielversprechend aus:


[ models.py ]--

class Chemical( models.Model ):
name = models.CharField();
plants = models.ManyToManyField( Plant, through="ChemicalSite" );
description = models.TextField();
general_notes = models.TextField();
properties = models.TextField();
class_solvent = models.BooleanField();
# snip viele Felder

class ChemicalSite( Chemical ):
chemical = models.OneToOneField( Chemical, related_name="variant_set",
parent_link=True ); # das hier muesste eigentlich ein ForeignKey sein
plant = models.ForeignKey( Plant );
class_informational = models.BooleanField();
class_hazardous = models.BooleanField();
sap_no = models.IntegerField();
# snip viele Felder

[/models.py ]--


Ich kann jetzt z.b. sowas machen:

| >>> from chemicals.models import *
| >>> cs = ChemicalSite.objects.all()[0]
| >>> cs.name
| u' Formaldehyd-Test Methode, Merckoquant'

Django merkt hier dass das "name"-Feld im Chemicals-Model ist und nicht
in ChemicalSite, und holt den Wert dann aus dem entsprechenden Datensatz
ohne dass ich dazu noch irgendwas tun müsste.

Das ist eigentlich genau was ich will, funktioniert aber nicht mehr
sobald ich einen neuen Datensatz anlege, weil ich keine Möglichkeit habe
einen bereits existierenden Elterndatensatz auszuwàhlen (warum auch,
ist ja im Normalfall nicht vorgesehen dass schon einer existiert).
Umgekehrt wird sobald das Kind gelöscht wird auch der Elterndatensatz
gelöscht, was ja auch nicht Sinn der Sache wàre da er ja für andere
Standorte unter Umstànden noch gebraucht wird.

Wenn's so nicht geht, wie geht's dann? Geht es überhaupt?

Zur Not würde ich meinem ChemicalSite-Model eine get()-Methode
verpassen, die der Reihe nach getattr() auf self und self.chemical
anwendet, allerdings müsste ich die dann in alle Models reinschreiben
damit die sich in den Views einheitlich verwenden lassen, und genau das
würd ich gern vermeiden :/

Ratlose Grüße,
Michael
 

Lesen sie die antworten

#1 Torsten Bronger
25/03/2009 - 19:28 | Warnen spam
Hallöchen!

Michael Ziegler schreibt:

ich muss hier(tm) Daten zu im Betrieb eingesetzten Chemikalien
speichern, von denen einige Felder allgemein gültig sind
(Handelsname, physikalische Daten), andere dagegen sind
standortabhàngig (Lieferant, Preis etc). Ich habe daher den
Datensatz aufgeteilt in zwei Models. Diese haben keine gemeinsamen
Felder und ich greife nur über das standortbezogene Model auf die
Daten zu, daher ist auch in jedem Falle klar um welchen Standort
es geht und eine eindeutige Zuordnung der Felder zu den Models ist
möglich.

Ich suche jetzt nach einer Möglichkeit zu verhindern dass ich
diesen Umstand jeder View die diese Daten nutzen soll einzeln
beibringen muss, zumal das nicht die einzige App ist in der ich
dieses Problem habe. Dazu hab ich mich mal in Vererbung von Models
eingelesen und das sieht auch recht vielversprechend aus:



Also in meinen Augen ist das kein Kandidat für eine "ist"-, sondern
für eine "hat"-Beziehung. Eine ChemicalSite _hat_ (einen Zeiger
auf) ein Chemical. Sprich: Du solltest den Kommentar in deinem
Quellcode-Auszug umsetzen.

Tschö,
Torsten.

Torsten Bronger, aquisgrana, europa vetus
Jabber-ID:

Ähnliche fragen