重写 ListSerializer 创建方法时 Django Rest Framework returns null id
Django Rest Framework returns null id when overriding ListSerializer create method
我正在试验 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()
我通过将我放在创建方法上的逻辑从 ListSerializer 移动到模型上的保存方法来实现我想要的。
所以基本上重新定义 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)
我正在试验 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()
我通过将我放在创建方法上的逻辑从 ListSerializer 移动到模型上的保存方法来实现我想要的。 所以基本上重新定义 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)