I want to get the category and subcategory with my product serializer, but it is showing me this error that subcategory object is not iterable. I don't know what is the problem I tried the same nested procedure and it worked previously for another field but not with subcategory .
#this is my model so you understand the relation
class Category(models.Model):
name = models.CharField(max_length=220)
def __str__(self):
return self.name
class Subcategory(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE)
name = models.CharField(max_length=220)
class Product(models.Model):
product_type_choices = [
('With Cylinder', 'With Cylinder'),
('Without Cylinder', 'Without Cylinder'),
]
setup_type_choices = [
('Yes', 'Yes'),
('No', 'No'),
]
user = models.ForeignKey(Vendor, on_delete=models.CASCADE)
name = models.CharField(max_length=220)
image = models.ImageField(null=True, blank=True)
product_type = models.CharField(max_length=220, null=True, blank=True, choices=product_type_choices)
setup_type = models.CharField(max_length=220, null=True, blank=True, choices=setup_type_choices)
subcategory = models.ForeignKey(Subcategory, on_delete=models.CASCADE, null=True, blank=True)
description = models.TextField(max_length=10000)
rating = models.DecimalField(max_digits=7, decimal_places=2, blank=True, null=True)
numReviews = models.IntegerField(null=True, blank=True, default=0)
old_price = models.DecimalField(max_digits=11, decimal_places=2)
discount = models.IntegerField(blank=True, null=True)
price = models.DecimalField(max_digits=12, decimal_places=2, blank=True, null=True)
countInStock = models.IntegerField(blank=True, null=True, default=0)
createdAt = models.DateTimeField(auto_now_add=True)
short_description = models.CharField(max_length=2000, blank=True, null=True)
isCampaign = models.BooleanField(blank=True, null=True, default=False)
_id = models.AutoField(primary_key=True, editable=False)
def save(self, *args, **kwargs):
self.price = Decimal(self.old_price * (100 - self.discount) / 100)
return super(Product, self).save(*args, **kwargs)
class Meta:
ordering = ['-createdAt']
def __str__(self):
return self.name
#this is my serializer
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = '__all__'
class SubcategorySerializer(serializers.ModelSerializer):
category = serializers.SerializerMethodField(read_only=True)
class Meta:
model = Subcategory
fields = '__all__'
def get_category(self, obj):
category = obj.category
serializer = CategorySerializer(category, many=True)
return serializer.data
class ProductSerializer(serializers.ModelSerializer):
user = serializers.SerializerMethodField(read_only=True)
subcategory = serializers.SerializerMethodField(read_only=True)
class Meta:
model = Product
fields = '__all__'
def get_user(self, obj):
user = obj.user
serializer = VendorSerializer(user, many=False)
return serializer.data
def get_subcategory(self, obj):
subcategory = obj.subcategory
serializer = SubcategorySerializer(subcategory, many=True)
return serializer.data
CodePudding user response:
You can use model serializers as fields to specify nested relationships.
You passed many=True
to your SubcategorySerializer
even though there is only one subcategory so it should be False
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = '__all__'
class SubcategorySerializer(serializers.ModelSerializer):
category = CategorySerializer(read_only=True)
class Meta:
model = Subcategory
fields = '__all__'
class ProductSerializer(serializers.ModelSerializer):
user = VendorSerializer(read_only=True)
subcategory = SubcategorySerializer(read_only=True, required=False)
class Meta:
model = Product
fields = '__all__'