добрый день , подскажите как добавлять характеристики товаров через json для каждой категории отдельно через админку и как их вывести.
models.py
```
class Category(MPTTModel):
class Meta:
verbose_name = 'Категории'
verbose_name_plural = 'Категории'
parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True,on_delete=models.CASCADE)
name = models.CharField(max_length=250,verbose_name='Имя категории')
slug = models.SlugField(unique=True)
def __str__(self):
try:
ancestors = self.get_ancestors(include_self=True)
ancestors = [i.name for i in ancestors]
except:
ancestors = [self.name]
return ' > '.join(ancestors[:len(ancestors) + 1])
def get_absolute_url(self):
return reverse('category_detail',kwargs={'slug': self.slug})
def get_fields_for_filter_in_template(self):
return ProductFeatures.objects.filter(
category=self,
use_in_filter=True
).prefetch_related('category').value('feature_key','feature_measure','feature_name','filter_type')
@property
def get_products(self):
return Product.objects.filter(category__name=self.name)
class Product(models.Model):
class Meta:
verbose_name = 'Продукт'
verbose_name_plural = 'Продукты'
order_with_respect_to='slug'
category = TreeForeignKey(Category, blank=True, null=True, related_name='category', verbose_name="Выберите категорию",on_delete=models.CASCADE)
title = models.CharField(max_length=250,verbose_name='Наименоватние продукта')
slug=models.SlugField(unique=True)
image1 = models.ImageField(verbose_name='Главное изображение')
image2 = models.ImageField(null=True,blank=True, verbose_name='Изображение 2')
image3 = models.ImageField(null=True,blank=True, verbose_name='Изображение 3')
image4 = models.ImageField(null=True,blank=True, verbose_name='Изображение 4')
image5 = models.ImageField(null=True,blank=True, verbose_name='Изображение 5')
characteristics = JSONField(blank=True,null=True)
available = models.BooleanField(default=True)
description = models.TextField(verbose_name='Описание товара',null=True)
price = models.DecimalField(max_digits=10,decimal_places=2,verbose_name='Цена')
def __str__(self):
return self.title
def get_model_name(self):
return self.__class__.__name__.lower()
def get_characteristics(self):
res={}
characteristics={
f.feature_key: {'feature_name':f.feature_name,'postfix':f.postfix_for_value}
for f in ProductFeatures.objects.filter(
feature_key__in=self.characteristics.keys()
).prefetch_related('category')
}
for feature_key,feature_value in self.characteristics.items():
postfix = characteristics[feature_key].get('postfix')
if postfix:
res[characteristics[feature_key]['feature_name']] = feature_value + ' ' + postfix
else:
res[characteristics[feature_key]['feature_name']] = feature_value
return res
def get_absolute_url(self):
return reverse('product_detail',kwargs={'slug':self.slug})
def get_feature_value_by_key(self,key):
return self.characteristics.get(key)
class ProductFeatureValidators(models.Model):
category = models.ForeignKey(Category,verbose_name='Категория',on_delete=models.CASCADE)
feature= models.ForeignKey(ProductFeatures, verbose_name='Характеристика',null=True,blank=True,on_delete=models.CASCADE)
feature_value= models.CharField(max_length=255,unique=True,null=True,blank=True,verbose_name='Значение хар-ки')
def __str__(self):
if not self.feature:
return f'Валидатор категории "{self.category.name}"- Хар-ка не выбрана'
return f'Валидатор категории"{self.category.name} | '\
f'Характеристика - "{self.feature.feature_name}"|'\
f'Значение - "{self.feature_value}"'
class ProductFeatures(models.Model):
RADIO='radio'
CHECKBOX='checkbox'
FILTER_TYPE_CHOICES=(
(RADIO,'Радиокнопка'),
(CHECKBOX,'Чекбокс')
)
feature_key = models.CharField(max_length=100,verbose_name='Ключ характеристики')
feature_name= models.CharField(max_length=255,verbose_name='Наименование характеристики')
category= models.ForeignKey(Category,verbose_name='Категория',on_delete=models.CASCADE)
postfix_for_value= models.CharField(
max_length=25,
null=True,
blank=True,
verbose_name='Постфикс для значения',
help_text=f'Для хар-к можно добавить постфикс'
)
use_in_filter=models.CharField(max_length=50,
default=False,
verbose_name='Использовать в фильтрации товаров на странице'
)
filter_type = models.CharField(
max_length=20,
verbose_name='Тип фильтра',
default=CHECKBOX,
choices=FILTER_TYPE_CHOICES
)
filter_measures=models.CharField(
max_length=50,
verbose_name='Единица измерения',
help_text='Единица измерения для фильтра'
)
def __str__(self):
return f'Категория - "{self.category.name}" | Характеристика -"{self.feature_name}"'
```