#django #django-rest-framework
#django #django-rest-framework
Вопрос:
Я изо всех сил пытаюсь сериализовать прародителя (-ов) отношения ManyToMany в моих моделях. В сериализаторе продукта я хочу перечислить верхний уровень, Category
основанный на SubCategory
выбранном на Product
. Мой код структурирован следующим образом:
models.py
class Category(models.Model):
...
name = models.CharField(
_('category name'),
max_length=255,
unique=False
)
...
class SubCategory(models.Model):
parent = models.ForeignKey(
Category,
on_delete=models.CASCADE,
related_name='children',
)
name = models.CharField(
_('category name'),
max_length=255,
unique=False
)
...
class Product(models.Model):
name = models.CharField(
_('product name'),
max_length=255,
unique=True
)
category = models.ManyToManyField(
SubCategory,
related_name='products'
)
...
serializers.py
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ['name']
class ProductsSerializer(serializers.ModelSerializer):
...
category = serializers.StringRelatedField(read_only=True, many=True)
parent_category = CategorySerializer(read_only=True, source='category.parent', many=True)
...
class Meta:
model = Product
fields = (
...
'parent_category',
'category',
...
)
В настоящее время поле parent_category не отображается в json-ответе.
Редактировать: serializers.py:
class ProductCategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ['name']
class ProductSubCategorySerializer(serializers.ModelSerializer):
class Meta:
model = SubCategory
fields = ['name']
class ProductsSerializer(serializers.ModelSerializer):
...
subcategory = ProductSubCategorySerializer(many=True, source='category')
category = ProductCategorySerializer()
...
class Meta:
model = Product
fields = (
...
'category',
'subcategory',
...
)
Текущий вывод:
[
{
"subcategory": [
{
"name": "sub category name",
"category": {
"name": "main category name"
}
},
],
}
]
желаемый результат:
[
{
"category": [
{
"name": "main category name"
},
...
],
"subcategory": [
{
"name": "sub category name",
},
...
],
}
]
Комментарии:
1. Попробуйте сначала связать
ProductsSerializer
сSubCategory
моделью, создающейserializer
для нее — например. вProductsSerializer
, избавьтесь отparent_category
и замените его наsubcategory = SubCategorySerializer(many=True)
— и как только вы это сделаетеSubCategorySerializer
, просто установитеcategory = CategorySerializer()
. Дайте мне знать, как это работает для вас.2. Спасибо, что нашли время помочь! Я получаю
Got AttributeError when attempting to get a value for field
подкатегорию` в сериализатореProductsSerializer
. Поле сериализатора может быть названо неправильно и не соответствовать какому-либо атрибуту или ключу вProduct
экземпляре. Исходный текст исключения был: объект ‘Product’ не имеет атрибута ‘subcategory’.`. Посмотрите на измененный код в редактировании сообщения на случай, если я вас неправильно понял.3. Хм, ты можешь попробовать установить
source="category"
вProductsSerializer
ssubcategory
? Если это тоже не сработает, просто используйтеcategory
вместоsubcategory
.4. Установка источника сработала для подкатегорий, но поле категории, использующее
ProductCategorySerializer()
возвращает"category": { "name": null },
в ответе. Сообщение еще раз обновлено.5. О, хорошо, теперь вам просто не хватает ссылки
ProductSubCategorySerializer
наProductCategorySerializer
, установивcategory = ProductCategorySerializer(source="parent")
— кстати, вы установили это вProductSubCategorySerializer
. Не забудьте также добавить его вfields
!
Ответ №1:
Полная serializers
настройка должна быть такой:
class ProductCategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ['name']
class ProductSubCategorySerializer(serializers.ModelSerializer):
category = ProductCategorySerializer(source="parent")
class Meta:
model = SubCategory
fields = ['name', 'category']
class ProductsSerializer(serializers.ModelSerializer):
...
subcategory = ProductSubCategorySerializer(many=True, source='category')
...
class Meta:
model = Product
fields = (
...
'subcategory',
...
)
Комментарии:
1. Если вам нужно другое представление, дайте мне знать подробности.
2. Извините, я должен был прояснить это при публикации. Я обновил свой пост текущим и желаемым результатом.
3. Похоже, вы хотите отделить подкатегорию от категории, создавая массив для каждой; если вы не возражаете, если я спрошу, не создаст ли это некоторую путаницу? Например, вы не знаете, какая подкатегория принадлежит к какой категории.
4. Вы совершенно правы. Я перепроектировал в своей голове. Ваш ответ правильный и отмечен впоследствии.