Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django FileField/ImageField从客户端完成文件上载时的验证_Django_Amazon S3_Django Rest Framework_Django Serializer - Fatal编程技术网

Django FileField/ImageField从客户端完成文件上载时的验证

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

当任何一个客户端想要上传一个文件时,它首先向Django服务器请求一个
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是的,这是正确的。你可以在这里了解更多