如何为此DRF嵌套序列化器分配外键

时间:2020-06-30 00:01:30

标签: python django django-rest-framework

我正在开发一个应用程序,该应用程序从我要保存的外部来源接收衣服的“供应商,产品类型和尺寸”,然后稍后更新尺寸表。

但我无法成功保存和更新

这是我的Models.py:

class Vendor(models.Model):
    name = models.CharField(max_length=50, null=False, blank=False)
    store_slug = models.CharField(max_length=100, null=False, blank=False)
    is_from_user = models.NullBooleanField(null=False, default=True)


    class Meta:
        ordering = ('name',)
        verbose_name_plural = 'Vendors'

    def __str__(self):
        return self.name


class ProductType(models.Model):
    vendor = models.ForeignKey(Vendor,related_name='producttypes', on_delete =models.CASCADE, null=False)

    name = models.CharField(max_length=50, null=False, blank=False)
    country = models.CharField(max_length=50, default="US", null=False, blank=True)
    gender = models.CharField(max_length=50, default="NONE", null=False)

    class Meta:
        ordering = ('name',)
        verbose_name_plural = 'ProductTypes'


    def __str__(self): 
        return self.name + ' | ' + self.vendor.name



class Size(models.Model):
    producttype = models.ForeignKey(ProductType,related_name='sizes', on_delete =models.CASCADE, null=False)
    
    name = models.TextField(max_length=50, null=False, blank=False)
    #ready = models.NullBooleanField(default=False)
    class Meta:
        ordering = ('name',)
        verbose_name_plural = 'Sizes'

    def __str__(self):
        return self.name + ' | ' + self.producttype.name 


class Chart(models.Model):
    size = models.ForeignKey(Size,related_name='charts', on_delete =models.CASCADE, null=False)

    bust = models.DecimalField(max_digits=5, decimal_places=2, default=0.0, null=True, blank=True)
    hip = models.DecimalField(max_digits=5, decimal_places=2, default=0.0, null=True, blank=True)
    waist = models.DecimalField(max_digits=5, decimal_places=2, default=0.0, null=True, blank=True)
    unit = models.CharField(max_length=50, default="CM", null=False, blank=True)

    class Meta:
        ordering = ('size',)
        verbose_name_plural = 'Charts'

    def __str__(self):
        return self.unit + ' Chart of | '+  self.size.name + ' | '

并在我的serializers.py中:

class ChartSerializer(serializers.ModelSerializer):

    class Meta:
        model = Chart
        fields = ('id', 'hip', 'bust', 'waist' , 'unit' ,'size')
        


class SizeSerializer(serializers.ModelSerializer):
    charts = ChartSerializer( many=True)
    class Meta:
        model = Size
        fields = ('id', 'name' ,'producttype', 'charts' )



class ProductTypeSerializer(serializers.ModelSerializer):
    sizes = SizeSerializer( many=True)

    class Meta:
        model = ProductType
        fields = ('id',  'name', 'country', 'gender','vendor', 'sizes')
        


class VendorSerializer(serializers.ModelSerializer):
    producttypes = ProductTypeSerializer(many=True)
    class Meta:
        model = Vendor
        fields = ('id', 'name', 'store_slug', 'producttypes')

    def run_validators(self, value):

        for validator in self.validators:
            if isinstance(validator, validators.UniqueTogetherValidator):
                self.validators.remove(validator)
        super(VendorSerializer, self).run_validators(value)

    def create(self, validated_data):
        producttypes = validated_data.pop('producttypes')
        v = Vendor.objects.get_or_create(**validated_data)   
        for producttype in producttypes:
            sizes = producttype.pop('sizes')
            p = ProductType.objects.get_or_create(vendor=v, **producttype)
            for size in sizes:
                charts = size.pop('charts')
                s = Size.objects.get_or_create(producttype=p, **size)  
                for chart in charts:
                    c = Chart.objects.get_or_create(size=size, **chart)
        return v

和我的views.py:

class VendorViewSet(viewsets.ModelViewSet):
    queryset = Vendor.objects.all()
    def get_serializer_class(self):
        if self.request.method in ['GET']:
            return VendorReadSerializer
        return VendorSerializer

class ProductTypeViewSet(viewsets.ModelViewSet):
    queryset = ProductType.objects.all()

    def get_serializer_class(self):
        if self.request.method in ['GET']:
             # Since the ReadSerializer does nested lookups
             # in multiple tables, only use it when necessary
            return ProductTypeReadSerializer
        return ProductTypeSerializer

class SizeViewSet(viewsets.ModelViewSet):
    queryset = Size.objects.all()

    def get_serializer_class(self):
        if self.request.method in ['GET']:
            return SizeReadSerializer
        return SizeSerializer


class ChartViewSet(viewsets.ModelViewSet):
    queryset = Chart.objects.all()

    def get_serializer_class(self):
        if self.request.method in ['GET']:
            return ChartReadSerializer
        return ChartSerializer


这就是我认为发布请求应该是的

data = {
    "name": "Adidas",
    "store_slug": "slugexamplecom",
    "producttypes": [
        {
        "name": "short",
        "gender": "female",
        "countr":"US",
        "sizes": [
            {
            "name": "Small",
            "charts":[{"unit":"CM",}]
            },
            {
            "name":"Medium",
            "charts":[{"unit":"CM","hip":"10","bust":"10","waist":"10"}]
            },
            {
            "name":"Large",
            "charts":[{"unit":"IN","hip":"20","bust":"20","waist":"20"}]
            }
            ]       
        },
    ]}

我的案子: 这是我从外部来源收到的, 我想遍历它们的大小并创建一个未准备好的图表 以便以后在我的仪表板上进行更新。 所有字段均应可更新。


 {"name": "Adidas",
 "store_slug": "aSlug",
 "producttypes": [{
    "name": "short",
    "gender": "female",
    "sizes": [{"name":"small"},{"name":"Medium"},{"name":"Large"} ]}
    ]}

我在做什么错? 如何保存和更新?并分配外键

#Currently the serializer is not valid
#if i remove the foreign keys fields i get a valid serializer with this error
#TypeError: int() argument must be a string, a bytes-like object or a number, not 'Vendor'

0 个答案:

没有答案