gpt4 book ai didi

python - Django REST 框架和文件上传(数据 URI)

转载 作者:太空宇宙 更新时间:2023-11-03 13:46:41 24 4
gpt4 key购买 nike

我想做的是

1) 允许用户选择图像2)获取图像并将其添加到 Canvas 3) 允许在 canavs 内部进行操作(调整大小)4) 按“上传”5) 获取 Canvas 并从中生成数据 URI

这一切在 JS 中都很有效,给我留下了三个隐藏字段:

<input type="hidden" id="imageData" name="imageData" />
<input type="hidden" id="imageName" name="imageName" />
<input type="hidden" id="imageCaption" name="imageCaption" />

这是Python代码

class Image(models.Model):
filePath = models.CharField(max_length=200)
imageCaption = models.CharField(max_length=200)
imageName = models.CharField(max_length=200)

class ImageSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Image
fields = ('filePath', 'imageCaption','imageName')

class ImageViewSet(viewsets.ModelViewSet):
queryset = Image.objects.all()
serializer_class = ImageSerializer

我在这里遗漏了一些关键点。

1) 我在哪里/如何拦截其余请求以解析/处理传入的 REST 帖子,以便能够分离数据 URI 并将图像存储在磁盘上?

2) 我可能不明白其中的一大堆 - 所以如果我还遗漏了什么,请告诉我


我认为诀窍在于覆盖序列化程序恢复字段方法。当它查找基于 model.FileField 构建的"file"字段时,我需要重定向框架以查找 dataUri 字段,该字段是传递的字段,但我需要实例化一个新字段,没有最大长度限制。将dataUri拉开,存入文件,并将file字段添加到解析资源的字典中,让框架继续按计划进行。在这种情况下不需要覆盖 pre_save,因为此代码需要在验证之前执行。

JS:

// angularJs controller submit method, using RESTAngular
$scope.submit = function() { //function(event) {

var someImg = {
file: ''
, dataUri: $scope.fileUrl
, caption: $scope.caption
}

ImagesResource.post(someImg )

}

python :

class ImageSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Image
fields = ('file', 'caption','id')

def saveImage(self, imgFileUri):
#parse dataUri and save locally, return local path
return 'somewhereOverTheBlah'

def restore_fields(self, data, files):
"""
Core of deserialization, together with `restore_object`.
Converts a dictionary of data into a dictionary of deserialized fields.
"""
reverted_data = {}

if data is not None and not isinstance(data, dict):
self._errors['non_field_errors'] = ['Invalid data']
return None

for field_name, field in self.fields.items():
print('a: ' + field_name)
if(field_name == 'file'):
field_name = 'dataUri'
field = fields.CharField()
try:
# restore using the built in mechanism
field.field_from_native(data, files, field_name, reverted_data)
# take the dataUri, save it to disk and return the Path
value = reverted_data[field_name]
path = self.saveImage(value)
# set the file <Path> property on the model, remove the old dataUri
reverted_data['file'] = path
del reverted_data[field_name]

except ValidationError as err:
self._errors[field_name] = list(err.messages)
else:
field.initialize(parent=self, field_name=field_name)
try:
field.field_from_native(data, files, field_name, reverted_data)
except ValidationError as err:
self._errors[field_name] = list(err.messages)

return reverted_data

最佳答案

如果您打算继续使用 viewsets.ModelViewSet然后您可以使用 GenericAPIView 可用的任何方法覆盖 - 在 this link 中简要提及并在 GenericAPIView 方法 部分 here 中进行了完整记录.

对您最有用的可能是 pre_savepost_save框架提供的 Hook ,您可以使用自己的方法覆盖这些 Hook ,从而将您自己的自定义代码添加到 View 中。 pre_save ,如您所料,在 View 保存发布的数据之前被调用。它的参数之一是即将保存的对象:

def pre_save(self, obj):

因此您可以在此时执行数据丰富等操作。

如果这对您来说不够灵活,那么构建您自己的自定义 View 非常简单,它可以让您完全控制 - 看看 chapter 3 of the tutorial以获得比我能提供的更好的解释!

更新 - 解决下面评论中提到的验证问题

DRF 在 pre_save 之前执行验证如果你的 file 被调用您的帖子数据中缺少字段您的更新将在您的自定义 pre_save 之前被拒绝代码有机会被执行。有几种解决方法:

  1. 添加 validate_<field_name>(self, attrs, source)序列化程序的方法(在您的情况下为 validate_file())。无论该字段是否已填充到您的帖子数据中,都会调用此方法,您可以在此处进行处理并添加 fileattrs在你归还它之前。请注意,如果 file将基于模型中的其他字段,然后实现模型级验证器 (validate(self, attrs)) 可能更合适。参见 here了解更多信息。

  2. 按照上面的建议构建自定义 View 。

关于python - Django REST 框架和文件上传(数据 URI),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18829392/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com