Очень долго искал альтернативу EAV для интернет-магазина на Django. Стояла задача не просто реализовать переменное количество атрибутов товаров но и реализовать их упорядочивание и вложенность в группы атрибутов а именно:
товар может принадлежать к нескольким категориям. Порядок категорий важен так как в них определены группы атрибутов характерные для каждой категории. Внутри групп атрибутов определены атрибуты которые могут быть нескольких типов по типу данных - число, текст, одно значение из списка, набор значений из списка. Просто одно поле JSON хороший вариант но он описывает произвольное количество атрибутов но не задает их порядок и вложенность. Пришлось колхозить два. На скринах показано какая структура данных в них.
parameters = models.JSONField: Ключ это id_группы атрибутов - id_атрибутов (атрибут может иметь разное значение в зависимости от того к какой группе атрибутов относится).
parameters_structure = models.JSONField
Написан виджет для адимнки:
class ProductAttributesField(forms.MultiValueField) который выглядит так
.
Вложенность определяется таблицами и связями между ними:
Product, Category, ProductInCategory, AttrGroup, AttrGroupInCategory, Attribute, AttributesInGroup, AttributeValue (варианты фиксированных значений для выбора)
Эти таблицы нужны по сути для адмимнки ну и хранят названия самих этих сущностей. Выглядит это так:
В форме товара (инлайны категорий можно перетаскивать для смены порядка категорий)
список категорий:
в форме редактирования категории:
Редактирование группы атрибутов:
Редактирование атрибута товара:
В интерфейсе администратора выглядит все как EAV но под капотом при любом изменении в структуре данных (добавили атрибут к группе атрибутов, изменили порядок следования категорий) происходит перезапись поля parameters_structure каждого связанного товара. Все ради того чтобы можно было обратится только к parameters товара при выборке и фильтрации товаров и к parameters и parameters_structure при отрисовке характреистик товара.
Эту логику сейчас реализовал в SAVE и DELETE промежуточных таблиц (ProductInCategory, AttrGroupInCategory, AttributesInGroup) но в процессе перенос в оттуда в формы измнения самих моделей (Product, Category, AttrGroup)
Работы еще много а оправдано ли? Получу ли я выигрыш в скорости по сравнению с EAV, а может было и решение проще?