Как "добавить" дополнительные данные (классификационные коды) в существующее поле
Я построил модель, которая должна представлять нашу продукцию на производстве. Наша продукция - это различные виды светильников. Некоторые из них имеют различные вариации, такие как различная цветотемпература, различный цвет корпуса, различная мощность, датчики или возможность диммирования.
на данный момент моя модель выглядит (немного укороченная) следующим образом
Теперь моя "проблема": Мы хотим классифицировать наши данные о продуктах с помощью ETIM-системы (например, ссылка для потолочного светильника )
Эта классификация имеет систему с одним классом на группу продуктов (например, "EC002892" для "Потолочный/настенный светильник"), кодами характеристик и кодами значений. Для некоторых кодов свойств требуется целое число, для других - булево, а для третьих - значения с кодом valuecode, где нужно выбрать ОДНО. Один пример для булевого свойства (его называют логическим):
Код "EF000137" - Описание "Dimmable" - Тип "Logical" -> Это должно быть "сопоставлено" с моим полем dimmable-BooleanField в классе LEDData.
Другой пример для свойства с кодом valuecode (они называют его буквенно-цифровым) Код "EF009350" - Описание "Цвет света" - Тип "Алфавитно-цифровой" -> Это должно быть "сопоставлено" с моим полем color-CharField в классе LightColour.
Сначала я попробовал создать отдельный класс для всех свойств, но я понятия не имею, как мне ссылаться на него из всех остальных классов. Один класс с множеством полей в каждом классе выглядит неправильно по многим причинам. Плюс... создавать формы позже будет не очень весело...
class ETIMClass(models.Model):
code = models.CharField(max_length=25)
short_description = models.CharField(max_length=100)
version = models.IntegerField()
etim_feature_codes = models.ManyToManyField('ETIMFeatureCode', through='ETIMFeatureCodeAdditions')
class ETIMFeatureCodeAdditions(models.Model):
etim_class = models.ForeignKey('ETIMClass', on_delete=models.PROTECT)
etim_feature_code = models.ForeignKey('ETIMFeatureCode', on_delete=models.PROTECT, null=True)
order = models.PositiveIntegerField()
class ETIMFeatureType(models.Model):
etim_feature_type = models.CharField(max_length=30)
short = models.CharField(max_length=10)
class ETIMFeatureCode(models.Model):
code = models.CharField(max_length=20)
value_codes = models.ManyToManyField('ETIMValueCode')
feature_type = models.ForeignKey(ETIMFeatureType, on_delete=models.PROTECT)
class ETIMValueCode(models.Model):
code = models.CharField(max_length=20)
text = models.CharField(max_length=150)
class PropertyType(models.Model):
type = models.CharField(max_length=25)
class Property(models.Model):
text = models.CharField(max_length=150, null=True, blank=True)
etim_code = models.ForeignKey(ETIMFeatureCode, null=True, blank=True,
on_delete=models.PROTECT)
type = models.ForeignKey(PropertyType, on_delete=models.PROTECT, null=False)
class ProductProperty(models.Model):
product_id = models.ForeignKey('ProductID', on_delete=models.PROTECT)
property = models.ForeignKey(Property, 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, 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
...
Последняя идея. Я сохраняю "путь" к каждому полю, которое мне нужно для конкретной функции и value-code в другом классе и использую getattr для поиска конкретного поля, но это тоже sh....
В конце я хочу экспортировать эти данные в XML-файл с этой (сокращенной) схемой
<REFERENCE_FEATURE_SYSTEM_NAME>ETIM-7.0</REFERENCE_FEATURE_SYSTEM_NAME>
<REFERENCE_FEATURE_GROUP_ID>EC000000</REFERENCE_FEATURE_GROUP_ID>
<FEATURE>
<FNAME>-</FNAME>
<FVALUE>-</FVALUE>
</FEATURE>
Для каждого классифицированного продукта в этом файле должны быть ВСЕ пары признак/значение в заранее определенном порядке. Хорошо, я могу сделать это полностью вручную, но если есть лучшее решение, я бы выбрал это.