首页 > 解决方案 > TypeError:'Variants' 对象在 django rest 框架中不可迭代

问题描述

在这里,我正在尝试创建一个添加产品 API。产品模型与 Category、Brand、Collection、Picture 和 Variants 模型相关。

这里的 Category、Picture 和 Variants 是与 Product 模型的 M2M 关系。从前端,一次发送所有数据块以创建产品对象。我使用 .set() 方法添加了类别和图片。

但是对于变体,我必须先创建变体对象,然后将它们添加到产品中。这个怎么做。我试过了,但我得到了这个错误。

TypeError:“变体”对象不可迭代

我正在发送这样的原始数据。

在此处输入图像描述

我的模型:

class Variants(models.Model):
    SIZE = (
        ('not applicable', 'not applicable',),
        ('S', 'Small',),
        ('M', 'Medium',),
        ('L', 'Large',),
        ('XL', 'Extra Large',),
    )
    AVAILABILITY = (
        ('available', 'Available',),
        ('not_available', 'Not Available',),
    )
    product_id = models.CharField(max_length=70,default='OAXWRTZ_12C',blank=True)
    price = models.DecimalField(decimal_places=2, max_digits=20,default=500)
    size = models.CharField(max_length=50, choices=SIZE, default='not applicable',blank=True,null=True)
    color = models.CharField(max_length=70, default="not applicable",blank=True,null=True)
    variant_image = models.ImageField(upload_to="products/images", blank=True)
    thumbnail = ImageSpecField(source='variant_image',
                               processors=[ResizeToFill(100, 50)],
                               format='JPEG',
                               options={'quality': 60})
    quantity = models.IntegerField(default=10,blank=True,null=True)  # available quantity of given product
    variant_availability = models.CharField(max_length=70, choices=AVAILABILITY, default='available')

    class Meta:
        verbose_name_plural = "Variants"

    def __str__(self):
        return self.product_id

class Product(models.Model):   
    
    merchant = models.ForeignKey(Seller,on_delete=models.CASCADE,blank=True,null=True)
    category = models.ManyToManyField(Category, blank=False)
    brand = models.ForeignKey(Brand, on_delete=models.CASCADE)
    collection = models.ForeignKey(Collection, on_delete=models.CASCADE)
    featured = models.BooleanField(default=False)  # is product featured?
    variants = models.ManyToManyField(Variants,related_name='products')

我的看法:

class ProductAddAPIView(CreateAPIView):
    permission_classes = [AllowAny]
    queryset = Product.objects.all()
    serializer_class = AddProductSerializer

我的序列化器:

类 AddProductSerializer(serializers.ModelSerializer):
变体 = VariantSerializer(many=True)

class Meta:
    model = Product
    fields = ['merchant','featured', 'top_rated','category','brand','collection',
              'name','description', 'main_product_image','best_seller','picture',
              'rating','availability','warranty','services','variants']
    # depth = 1

def create(self, validated_data):
     #user = self.context['request'].user
     picture_data = validated_data.get('picture')
     merchant = validated_data.get('merchant')
     category_data = validated_data.get('category')
     featured = validated_data.get('featured')
     top_rated = validated_data.get('top_rated')
     brand = validated_data.get('brand')
     collection = validated_data.get('collection')
     name = validated_data.get('name')
     description = validated_data.get('description')
     main_product_image = validated_data.get('main_product_image')
     best_seller = validated_data.get('best_seller')
     rating = validated_data.get('rating')
     availability = validated_data.get('availability')
     warranty = validated_data.get('warranty')
     services = validated_data.get('services')

    #variants_logic

     variants_data = validated_data.get('variants')
     for variants_data in variants_data:
         abc = Variants.objects.create(**variants_data)

     #products-logic

     product = Product.objects.create(featured=featured,top_rated=top_rated,
                                      brand=brand,collection=collection,
                                      name=name,description=description,
                                      main_product_image=main_product_image,
                                      best_seller=best_seller,rating=rating,
                                      availability=availability,warranty=warranty,
                                      services=services,merchant=merchant)
     product.save()
     #category_data = Category.objects.filter(category__in=category_data)
     product.category.set(category_data)
     product.picture.set(picture_data)
     product.variants.set(abc)
     return product

我的网址:

path('api/addproducts', views.ProductAddAPIView.as_view(), name='api-addproducts'),

问题显示在行上product.variants.set(abc)

标签: djangoapidjango-rest-frameworkpostmaniterable

解决方案


我在循环中使用 .add 方法而不是 .set() 并且它有效。今天学到了一个很棒的东西。

我的工作序列化程序是:

class  AddProductSerializer(serializers.ModelSerializer):    
    variants = VariantSerializer(many=True)
   
    class Meta:
        model = Product
        fields = ['merchant','featured', 'top_rated','category','brand','collection',
                  'name','description', 'main_product_image','best_seller','picture',
                  'rating','availability','warranty','services','variants']
        # depth = 1

    def create(self, validated_data):
         #user = self.context['request'].user
         picture_data = validated_data.get('picture')
         merchant = validated_data.get('merchant')
         category_data = validated_data.get('category')
         featured = validated_data.get('featured')
         top_rated = validated_data.get('top_rated')
         brand = validated_data.get('brand')
         collection = validated_data.get('collection')
         name = validated_data.get('name')
         description = validated_data.get('description')
         main_product_image = validated_data.get('main_product_image')
         best_seller = validated_data.get('best_seller')
         rating = validated_data.get('rating')
         availability = validated_data.get('availability')
         warranty = validated_data.get('warranty')
         services = validated_data.get('services')

        #variants_logic

         variants_data = validated_data.get('variants')


         #products-logic

         product = Product.objects.create(featured=featured,top_rated=top_rated,
                                          brand=brand,collection=collection,
                                          name=name,description=description,
                                          main_product_image=main_product_image,
                                          best_seller=best_seller,rating=rating,
                                          availability=availability,warranty=warranty,
                                          services=services,merchant=merchant)
         product.save()
         #category_data = Category.objects.filter(category__in=category_data)
         product.category.set(category_data)
         product.picture.set(picture_data)
         for variants_data in variants_data:
             abc = Variants.objects.create(**variants_data)
             product.variants.add(abc)
         
         return product

推荐阅读