重写ListSerializer create方法时,Django Rest Framework返回null id

时间:2015-04-12 05:07:39

标签: python django django-rest-framework

我正在试验https://github.com/tomchristie/django-rest-framework/issues/1116上描述的问题。

我有一个ListSerializer,它改变了传入的formData的一些字段......我需要这个,因为我必须为每个上传的图像提取宽度和高度。 在此之前,我尝试在我的模型上覆盖save()方法,但它不起作用......

class ImageUrl(models.Model):
    file = models.ImageField(upload_to="%Y/%m/%d")
    createdAt = models.DateTimeField(default=datetime.now, editable=False)
    modifiedAt = models.DateTimeField(default=datetime.now)
    width = models.PositiveIntegerField(editable=False, default=0)
    height = models.PositiveIntegerField(editable=False, default=0)
    description = models.TextField(blank=True, default="")

    class Meta:
        ordering = ('createdAt',)

    def save(self, *args, **kwargs):
        # If the obj already exists update its modifiedAt attr
        if self.id:
            #time_format = "%a %b %d %H:%M:%S %Y"
            #today =
            #self.modifiedAt = today.strftime(time_format)
            self.modifiedAt = datetime.datetime.today()
        super(ImageUrl, self).save(*args, **kwargs)


class ImageUrlListSerializer(serializers.ListSerializer):

    def to_internal_value(self, data):
        ret = []
        errors = []
        #import pdb; pdb.set_trace()
        for item in data.getlist("file"):
            aux_item = {"file": item}
            try:
                validated = self.child.run_validation(aux_item)
            except ValidationError as exc:
                errors.append(exc.detail)
            else:
                ret.append(validated)
                errors.append({})
        if any(errors):
            raise ValidationError(errors)

        return ret

    def create(self, validated_data):
        #print "Validated data: ", validated_data
        images = [ImageUrl(**item) for item in validated_data]
        for img in images:
            self._set_image_attributes(image=img)
        saved_images = ImageUrl.objects.bulk_create(images)
        return saved_images

    def _set_image_attributes(self, image):
        ''' On save, update timestamps '''
        #time_format = "%a %b %d %H:%M:%S %Y"
        if not image.id:
            image.createdAt = datetime.datetime.today()
            pil_image = PIL.Image.open(image.file)
            width, height = pil_image.size
            image.width = width
            image.height = height
        image.modifiedAt = datetime.datetime.today()

1 个答案:

答案 0 :(得分:0)

通过将我放在createSerializer上的create方法的逻辑移动到模型上的save方法,我实现了我想要的。 所以基本上重新定义create方法就是问题......这就是它现在的样子:

class ImageUrl(models.Model):
    file = models.ImageField(upload_to="%Y/%m/%d")
    createdAt = models.DateTimeField(default=datetime.now, editable=False)
    modifiedAt = models.DateTimeField(default=datetime.now)
    width = models.PositiveIntegerField(editable=False, default=0)
    height = models.PositiveIntegerField(editable=False, default=0)
    description = models.TextField(blank=True, default="")

    class Meta:
        ordering = ('createdAt',)

    def save(self, *args, **kwargs):
        if not self.id:
            #time_format = "%a %b %d %H:%M:%S %Y"
            self.createdAt = datetime.today()
            pil_image = PIL.Image.open(self.file)
            width, height = pil_image.size
            self.width = width
            self.height = height
        # If the obj already exists update its modifiedAt attr only
        self.modifiedAt = datetime.today()
        super(ImageUrl, self).save(*args, **kwargs)