Форум сайта python.su
Подскажите как реализовать следующее:
есть сущность “объявление”. В зависимости от типа(или объекта) этого объявления (комп, ноут, плеер), нужно прикрутить к нему набор свойств как общих (цена, вес, …), так и специфических (громкость, процессор, формат файлов, …).
1. Сначала думал через наследование, как написано в доке:
class Advertisement(models.Model):
title = models.CharField()
price = models.IntegerField()
…
class Meta:
abstract = True
class CompOptions(Advertisement)
cpu = models.CharField()
ram = models.CharField()
class PlayerOptions(Advertisement)
…
Но мне не нравится то что создаются таблицы compoptions, noutoptions, и т.д. где поля title, price просто дублируются, т.е. с точки зрения БД никакого наследование нету :(
2. держать все свойства в одной таблице тоже плохой вариант, так как получится 20 и более полей, из которых штук 5 общих, а остальные будут специфические для каждоготипа техники. Получится много пустых полей.
3. Выделить таблицу common_options, куда занести все общие свойства, потом создать для каждого девайса по таблице с его спец. свойствами. (благо таких будет ограниченное количество и потом добавить еще будет несложно)
Проблема в том, что это только мои теоретические догадки, не получается “набросать” схему БД.
Подозреваю что надо через связи многие-ко-многим, через дополнительные промежуточные таблицы.
4. В идеале хочется чтобы все было масштабируемо, и избежать варианты создания таблицы свойств для каждого типа товара.
Самое плохое в том что я не могу нарисовать для этого схему БД :(
думал “забить” на БД и заюзать средства Джанго, а он мне уже нагенерит нужных таблиц :)
Приветствуются любые ответы, ткните носом что почитать. (только плиз не в гугл, “БД для чайников” и т.д.)
Спасибо.
Офлайн
Вообще-то у реляционных баз данных “наследования” в принципе нету. Есть связи только.
Почитайте нормальной форме. Будет понятнее.
Вот, например, такая схема:
class ObjPropeties(models.Model):
""" Возможные свойства """
name = ...
class AdvType(models.Model):
""" Тип обьявления с сылками на свои свойства"""
name = ...
properties = ManyToMany(ObjProp)
class Advertisement(models.Model):
""" Объявление - связано с типом и с дополнительными свойствами"""
type = model.ForeignKey(AdvType)
special_properties = ManyToMany(ObjProp, blank=True)
title = models.CharField()
price = models.IntegerField()
Отредактировано (Фев. 10, 2010 19:02:14)
Офлайн
Нет, не так.
Офлайн
FerromanЯ ожидал, что Джанга реализует это наследование как-то эффективнее :), а не просто дублированием полей. Такая реализация я бы сказал противоречит принципам построения БД. Она вроде не нарушает 3 нормальные формы, но я не вижу смысла использовать эту фичу. (может ошибаюсь, так кажется на первый взгляд)
Вообще-то у реляционных баз данных “наследования” в принципе нету. Есть связи только.
Почитайте нормальной форме. Будет понятнее.
Но возможно дублирование свойств в “типе” и “индивидуальных”.может имелось ввиду дублирование в “обявление” и “индивидуальных” ? Так как в “типе” (AdvType) будет только список возможных девайсов, без каких либо свойств. Если так, то это будет полностью на моей совести и должен следить за тем, чтобы общие свойства вынести в Advertisement, а специфичные в ObjPropeties
Нет, не так.Хм ? Что не так ? Все не так ? :) В любом случае что-то уже обрисовывается, отпишусь, когда получится или же не получится - буду спрашивать.
Отредактировано (Фев. 11, 2010 14:35:22)
Офлайн
Так как в “типе” (AdvType) будет только список возможных девайсов, без каких либо свойств.Значит я не правильно понял условие задачи. “Общие” свойства разве не есть “общие” для определённого типа устройств?
Хм ? Что не так ? Все не так ?Да, всё не так. Мой ответ, как минимум, неполон, а скорее всего и вообще не правилен. Надо подумать, как это красивше сделать.
еще очень интересует такая вещь как хранение в поле одной таблицы названия других таблиц. насколько адекватно такое решение ?Абсолютно неадекватное и не нужное. Для таких вещей и существуют отношения.
Офлайн
FerromanВсе правильно, пункт 3 вычеркиваем. Есть просто индивидуальные свойства для каждого типа устройств, как сказано в п.2. Более глубокой детализации нету.
Значит я не правильно понял условие задачи. “Общие” свойства разве не есть “общие” для определённого типа устройств?
Я себе представил так:
1. Есть общие свойства для всех устройств. (неизменные. Цена, к примеру.)
2. Есть обобщённые свойства для определённого типа устройств (у каждого типа - свои) (ёмкость и цвет у кружки)
3. Есть (или нету) индивидуальные свойства для отдельного устройства (дополнительно к типам) (картинка на кружке)
Или не так?
Офлайн
Значит сделал так:
class AdvObjectParam(models.Model):
""" Список всех возможных параметров характеризующих недвижимость """
name = models.CharField(unique=True, max_length=15)
class HouseType(models.Model):
""" тип жилья: квартира, оффис, помещения, земельный участок, ... """
name = models.CharField(unique=True, max_length=15)
advobjectparam = models.ManyToManyField(AdvObjectParam, blank=True, null=True)
class Adv(models.Model):
""" Объявление """
title = models.CharField(max_length=100)
date_create = models.DateTimeField(auto_now_add=True)
housetype = models.ForeignKey(HouseType)
class ParamValue(models.Model):
""" Соответствие объявление->параметр жилья->значение параметра """"
advobject = models.ForeignKey(Adv)
advobjectparam = models.ForeignKey(AdvObjectParam)
value = models.CharField(max_length=25)
{% for adv in adv_list %}
{{ adv.title }}
{% for param in adv_params.ADV_ID %}
параметр:{{ param.advobjectparam }}
значение:{{ param.value }}
{% endfor %}
{% endfor %}
{% for element in adv_params.items %}
{% ifequal adv.id element.0 %}
выводим параметры, для данного объявления
{% endif %}
{% endfor %}
Офлайн
Хочется создать переменную {% var adv_id = {{ adv.id }}%} и потом ее заюзать. Но объявлять переменные в темплейте нельзяЭто замечательное свойство джанговских темплейтов, специально для таких случаев.
Офлайн