Предисловие, есть готовый сайт на django с базой знаний по игре. Под капотом категории в базе знаний реализованы в отдельных таблицах postgresql c полями описание объекта и набором свойств для сравнения которые для каждой категории свои.
Пока категорий в базе не очень большое количество, и соответственно можно ее безболезненно переделать.
Хочу унифицировать объекты в базе в одну таблицу с полем описания объекта и и.д., а свойства и их значения вынести в две отдельные таблицы. После чего просто делать связь объекта со свойствами и их значениями.
Вопрос в том стоит ли это делать? И есть ли какие то другие варианты решения задачи?
upd.
Вот какую схему базы данных я имел виду, взял ее с онлайн магазина.
Модель категории, например: Оружие(подкатегория Мечи), Зелья, Доспепи и т.д.
class Category(MPTTModel, ModerationBaseModel):
"""
Category of item
extend ItemBaseModel
which has slug, name,
description, keywords
"""
slug = models.CharField(
_("Slug"),
default="",
unique=True,
max_length=250)
name = models.CharField(
_("Name"),
default="",
max_length=250)
title = models.CharField(
_("Title"),
blank=True,
default="",
max_length=250)
description = models.CharField(
_("Description"),
blank=True,
default="",
max_length=250)
keywords = models.CharField(
_("Keywords"),
blank=True,
default="",
max_length=250)
parent = TreeForeignKey(
'self',
null=True,
blank=True,
related_name='children',
verbose_name=_('Parent'))
image = models.ImageField(
upload_to='category_images/',
blank=True,
default="",
verbose_name=_('Image'))
def __str__(self):
return self.name
class Meta:
verbose_name = _('Category')
verbose_name_plural = _('Categories')
class MPTTMeta:
order_insertion_by = ['name']
Модель для страницы в базе знаний, например: "меч Ледяная Скорбь"
class Item(ModerationBaseModel):
slug = models.CharField(
_("Slug"),
default="",
blank=True,
db_index=True,
max_length=250)
name = models.CharField(
_("Name"),
default="",
max_length=250)
title = models.CharField(
_("Title"),
blank=True,
default="",
max_length=250)
description = models.CharField(
_("Description"),
blank=True,
default="",
max_length=250)
keywords = models.CharField(
_("Keywords"),
blank=True,
default="",
max_length=250)
image = models.ImageField(
upload_to='Itemimeges/',
blank=True,
default="",
verbose_name=_('Image'))
category = models.ForeignKey(
Category,
on_delete=models.CASCADE,
related_name='categories',
blank=True,
null=True,
verbose_name=_('Category'))
description = models.TextField(blank=True,)
full_text = models.TextField(blank=True,)
def save(self, *args, **kwargs):
if self.category:
super(Item, self).save(*args, **kwargs)
# we create properties if not exist
for cp in CategoryProperty.objects.filter(category=self.category):
pp = ItemProperty.objects.filter(category_property=cp,
Item=self)
if not pp:
pp = ItemProperty(category_property=cp,
Item=self, value="--")
pp.save()
def __str__(self):
return self.name
class Meta:
verbose_name = _('Item')
verbose_name_plural = _('Items')
Модель для набора свойств в определенной категории, например: Категория Мечи - свойства урон, скорость, дпс и т.д.
class CategoryProperty(ModerationBaseModel):
name = models.CharField(
_("Name"),
default="",
max_length=250)
category = models.ForeignKey(
'Category',
on_delete=models.CASCADE,
related_name='categories_property',
verbose_name=_('Category'))
def __str__(self):
return self.name
class Meta:
verbose_name = _('Category property')
verbose_name_plural = _('Category properties')
И последняя модель для хранения значений свойств конкретного объекта, например: "Ледяная Скорбь" - урон - 100, скорость - 20, дпс - 500.
class ItemProperty(ModerationBaseModel):
category_property = models.ForeignKey(
CategoryProperty,
on_delete=models.CASCADE,
related_name='category_property',
verbose_name=_('Propery'))
value = models.CharField(
_("Value"),
default="",
max_length=250)
Item = models.ForeignKey(
'Item',
on_delete=models.CASCADE,
related_name='properties_Item',
verbose_name=_('Item'))
def __str__(self):
return self.value
class Meta:
verbose_name = _('Item property')
verbose_name_plural = _('Item properties')
Но получается что если в категории 100 страниц а у каждой страницы 10 свойств, выходит 100*10 = 1000 записей в базе данных, и еще плюс 10 других категорий 1000*10 = 10000 записей (при нынешней реализации это будет просто 1000 записей и 10 различных моделей для каждой категории).
Но при подходе с унифицированными страницами и отдельными свойствами (который я описал выше) все управление данными ведется с админки и добавляя новые категории не нужно править код моделей. Вот у меня и вопрос стоит ли все это того?
И еще я знаю реализации магазинов где категории товаров также жестко прописываются в моделях, вот пример
Заготовка под магазин django-SHOP
За пример беру магазины, поскольку база знаний этот тот же самый магазин только без корзины =).