SO, das lässt mir dann doch keine Ruhe...
ich habe jetzt mal deinen Vorschlag so übernommen.
Es gibt allerdings einige Eigenschaften die ich in meinen Daten etwas "genauer" habe. Z. B. gibt es für die Eigenschaft Lichtfarbe in dieser Klassifizierung nur ein Feld mit einer Range. In Wirklichkeit hängen da aber noch einige zusätzliche Daten dran, weshalb ich es einfacht nicht "einfach" mit in meine Product-Klasse packen kann.
VIelleicht hol ich einfach mal etwas aus

Wenn ich eine Leuchte mit einstellbarer Lichtfarbe (z. B. 3000K / 4000K / 5700K) habe, müßte ich in die XML-Datei
einfügen..genauso auch bei der Leistung.
In meinem Modell habe ich aber eine eigene Klasse "PhotometricData" in der zu jeder Lichtfarbe/Leistung noch zusätzliche Daten hinterlegt sind (z. B. ändert sich je nach Lichtfarbe der Lichtstrom).
Ich habe dann also bei der oben genannten Leuchte pro Lichtfarbe jeweils eine Instanz von PhotometricData.
Der extremste Fall aktuell ist eine Leuchte bei der man Abstrahlwinkel, Lichtfarbe und Leistung auf jeweils 3 unterschiedliche Werte einstellen kann...und für jede Möglichkeit muß ich dann in meinem jetzigen Entwurf eine Instanz von PhotometricData erstellen.
Ich müßte dann also auch in dieser Klasse auf meine ProductProperty Klasse verweisen weil ja auch in dieser Klasse Properties sind zu denen es einen ETIM-Feature Code gibt.
Das Zusammenbauen des jeweiligen "Range-Strings" für die XML-Datei sollte dann ja kein Problem sein bzw. ist in diesem Stadium erstmal Nebensache
Hier mal der relevante Auszug. Die anderen Klassen sind glaube ich erstmal nicht so wichtig
Code: Alles auswählen
# Ich nutze diese Klasse für Product-Typ und Sub-Typ. z. B. haben wir eine Klasse LED-Leuchten, darunter gibts dann Sub-Klassen für LED-Panels, Wand-/Deckenleuchten usw...deshalb auch der ForeignKey auf self. Oder würde es mehr Sinn ergeben, wenn ich das in ProductType und (z. B.) ProductSubType aufteile?
class ProductType(models.Model):
type_text = models.CharField(verbose_name=_('Produkt-Kategorie'), max_length=100)
main_type = models.ForeignKey('self', verbose_name=_('Hauptkategorie'), null=True, on_delete=models.PROTECT)
etim_class = models.ForeignKey('ETIMClass', verbose_name=_('ETIM Klasse'), null=True, on_delete=models.PROTECT)
# Die einzelnen Feature-Codes sollen laut Guidelines in einer festen Reihenfolge in der XML-Datei liegen, deshalb diese Intermediate-Klasse.
ETIMFeatureCodeAdditions(models.Model):
etim_class = models.ForeignKey('ETIMClass', verbose_name=_('ETIM Klasse'), on_delete=models.PROTECT, null=True)
etim_code = models.ForeignKey('ETIMFeatureCode', verbose_name=_('ETIM Code'), on_delete=models.PROTECT, null=True)
order = models.PositiveIntegerField(verbose_name=_('Reihenfolge'))
class ETIMClass(models.Model):
code = models.CharField(verbose_name=_('ETIM Class Code'), max_length=25)
short_description = models.CharField(verbose_name=_('Kurzbeschreibung'), max_length=100)
version = models.IntegerField(verbose_name='Version')
etim_feature_codes = models.ManyToManyField('ETIMCode', through='ETIMFeatureCodeAdditions', verbose_name=_('ETIM Codes'))
class ETIMFeatureCode(models.Model):
feature_code = models.CharField(verbose_name=_('ETIM Feature Code'), max_length=20)
value_codes = models.ManyToManyField('ETIMValueCode', verbose_name=_('ETIM Value Code'))
class ETIMValueCode(models.Model):
value_code = models.CharField(verbose_name=_('ETIM Value Code'), max_length=20)
class PropertyType(models.Model):
type = models.CharField(verbose_name=_('Feldtyp'), max_length=25)
class Property(models.Model):
text = models.CharField(verbose_name=_('Eigenschafts-Text'), max_length=150, null=True, blank=True)
etim_code = models.ForeignKey(ETIMFeatureCode, verbose_name=_('ETIM Code'), null=True, blank=True,
on_delete=models.PROTECT)
type = models.ForeignKey(PropertyType, verbose_name=_('Feldtyp'), on_delete=models.PROTECT, null=False)
class ProductProperty(models.Model):
product = models.ForeignKey('Product', verbose_name=_('Product'), on_delete=models.PROTECT)
property = models.ForeignKey(Property, verbose_name=_('Eigenschaft'), on_delete=models.PROTECT, null=False)
char_value = models.CharField()
int_value = models.IntegerField()
datetime_value = models.DateTimeField()
bool_value = models.BooleanField()
decimal_value = models.DecimalField(max_digits=7, decimal_places=3)
etim_value_code = models.ForeignKey(ETIMValueCode, verbose_name=_('ETIM Value Code'), on_delete=models.PROTECT,
null=True)
@property
def value(self):
if self.product_property.type == "integer":
return self.int_value
elif self.product_property.type == "char":
return self.char_value
elif self.product_property.type == "datetime":
return self.datetime_value
elif self.product_property.type == "boolean":
return self.bool_value
elif self.product_property.type == "decimal":
return self.decimal_value
elif self.product_property.type == "etim":
return self.etim_value_code.value_code
class Product(models.Model):
product_type = models.ForeignKey(ProductType, verbose_name=_('Produktkategorie'),
on_delete=models.PROTECT)
manufacturer = models.ForeignKey('Manufacturer', verbose_name=_('Hersteller'), null=True, blank=True,
default=None, on_delete=models.PROTECT)
trademark = models.ForeignKey('Trademark', verbose_name=_('Marke'), on_delete=models.PROTECT, null=True,
blank=True)
harmonised_standards = models.ManyToManyField('HarmonisedStandards', verbose_name=_('gültige Normen'))
class PhotometricData(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
lum_flux_min = models.IntegerField(verbose_name=_('Lichtstrom min. (lm)'))
power_min = models.DecimalField(verbose_name=_('Leistung min. (W)'), max_digits=6, decimal_places=2, null=True)
amperage = models.IntegerField(verbose_name=_('Stromstärke (mA)'), null=True)
reference_settings = models.BooleanField(verbose_name=_('Referenzeinstellungen?'), default=False)
light_colour = models.ForeignKey(LightColour, verbose_name=_('Lichtfarbe'), on_delete=models.PROTECT)
colour_consistency = models.DecimalField(verbose_name=_('Farbkonsistenz'), max_digits=2, decimal_places=1,
null=True)
beam_angle = models.ForeignKey('BeamAngles', verbose_name=_('Abstrahlwinkel'), null=True, blank=True,
on_delete=models.PROTECT)