首页 > 解决方案 > Postman 在 django rest 框架中创建产品对象时给出“该字段已存在”

问题描述

我正在尝试制作一个发布 api,商家可以通过在商家仪表板中选择类别、品牌、集合来添加产品。但是当我尝试从邮递员发送原始 json 数据时,它说类别、品牌和集合已经存在。

在此处输入图像描述

在此处输入图像描述

我的模型:

class Seller(models.Model):
    seller = models.OneToOneField(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, null=True)
    business_name = models.CharField(max_length=50, blank=True)
    phone_num = models.CharField(max_length=50, blank=True)

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)

我的看法:

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

我的序列化器:

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

    def create(self, validated_data):
         user = self.context['request'].user
         category_data = validated_data.pop('category',None)
         brand_data = validated_data.pop('brand',None)
         collection_data = validated_data.pop('collection',None)
         product = Product.objects.create(merchant=user,**category_data,**brand_data,**collection_data)
         return product

我的网址:

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

标签: djangoapipostdjango-rest-frameworkpostman

解决方案


class AddProductSerializer(serializers.ModelSerializer):
    category = CategorySerializer(many=True,required=True)
    brand = BrandSerializer(required=True)
    ....

上面的嵌套序列化程序(例如categorybrand字段)假设它正在为类别和品牌创建新实例。即使您传递了一个,id因为它read_only默认情况下该字段是 inModelSerializer所以它永远不会被包含在validate_data.

如果序列化程序的使用仅用于编写,我想您可以使用PrimaryKeyRelatedField

class AddProductSerializer(serializers.ModelSerializer):
    category = serializers.PrimaryKeyRelatedField(many=True, required=True, queryset=Category.objects.all())
    brand_id = serializers.PrimaryKeyRelatedField(required=True, queryset=Brand.objects.all())

    class Meta:
        model = Product
        fields = [
            # other fields here
            "brand_id", # previously "brand"
        ]

drf 文档: https ://www.django-rest-framework.org/api-guide/relations/#primarykeyrelatedfield


推荐阅读