Django FileField/ImageField从客户端完成文件上载时的验证
当任何一个客户端想要上传一个文件时,它首先向Django服务器请求一个Django FileField/ImageField从客户端完成文件上载时的验证,django,amazon-s3,django-rest-framework,django-serializer,Django,Amazon S3,Django Rest Framework,Django Serializer,当任何一个客户端想要上传一个文件时,它首先向Django服务器请求一个pre-signedURL,然后服务器生成一个pre-signedURL并将其发送回客户端 客户端可以使用此URL将文件直接上载到S3。上传成功后,客户端将文件密钥发送回服务器(文件密钥也与URL一起出现在服务器给出的响应中) 现在我对如何通过FileField验证感到困惑,因为我只有文件密钥,而没有实际的文件。例如: class Company(models.Model): name = models.CharFie
pre-signed
URL,然后服务器生成一个pre-signed
URL并将其发送回客户端
客户端可以使用此URL将文件直接上载到S3。上传成功后,客户端将文件密钥发送回服务器(文件密钥也与URL一起出现在服务器给出的响应中)
现在我对如何通过FileField验证感到困惑,因为我只有文件密钥,而没有实际的文件。例如:
class Company(models.Model):
name = models.CharField(max_length=100)
logo = models.ImageField(null=True)
def __str__(self):
return f'name:{self.name}'
class CompanySerializer(serializers.ModelSerializer):
CLIENT_COMPANY_LOGO_KEY = 'logo'
def to_internal_value(self, data):
# Replace file/image keys with file/image instances so that they can pass validation.
if data.get(self.CLIENT_COMPANY_LOGO_KEY):
try:
data[self.CLIENT_COMPANY_LOGO_KEY] = default_storage.open(data[self.CLIENT_COMPANY_LOGO_KEY])
except (TypeError, OSError, ParamValidationError):
pass
return super().to_internal_value(data)
def process_logo(self, validated_data):
logo = validated_data.get(self.CLIENT_COMPANY_LOGO_KEY)
if logo:
# Replace file/image instances with keys.
validated_data[self.CLIENT_COMPANY_LOGO_KEY] = logo.name
return validated_data
def create(self, validated_data):
validated_data = self.process_logo(validated_data)
company = super().create(validated_data)
return company
在序列化程序中,我首先使用default\u存储
将文件键替换为实际文件,该存储使用django存储
连接到S3。然后,一旦成功验证了文件,我将再次在过程_logo
功能中用文件键替换实际文件
我用文件替换实际文件的原因是,它减慢了create
方法的速度(最多30秒)
我觉得这是一种非常粗糙的方法,我想知道是否有更好的方法来处理这种情况。我是否应该将文件字段
/图像字段
替换为字符字段
,而不进行任何验证
或者用芹菜做验证?但如果验证失败怎么办?服务器应如何在后台通知客户端验证因某种原因失败?您返回的URL允许客户端将任意文件上载到S3存储桶?@IainShelvington是的,这是正确的。你可以在这里了解更多