简体   繁体   English

Django 使用 Boto3 将表单上传到 AWS S3 会导致空文件

[英]Django Form upload to AWS S3 with Boto3 results in empty file

I am having a multipart/form-data form that should upload to a S3 bucket, using Boto3.我有一个多部分/表单数据表单,应该使用 Boto3 上传到 S3 存储桶。

All is happening as expected, but at the end, the file at the S3 bucket has 0 bytes.一切都按预期进行,但最后,S3 存储桶中的文件有 0 个字节。

forms.py: forms.py:

class DropOffFilesForm(forms.ModelForm):
    file = forms.FileField(error_messages={'invalid_type': _("Please upload only PDF, JPG, PNG, XLS(x), DOC(x) files")},
                       validators=[
                           FileTypeValidator(allowed_types=['application/pdf', 'image/*', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'], allowed_extensions=['.pdf', '.png', '.jpg', '.doc', '.docx', '.xls', '.xlsx'])], required=False)
    description = forms.CharField(widget=forms.Textarea, label=_("Description"), required=False)

    def clean_description(self):
        data = self.cleaned_data['description']
        return data

    class Meta:
        model = DropOffFiles
        exclude = ['filename',]
        fields = ['file', 'description']

views.py:视图.py:

file_form = DropOffFilesForm(request.POST, request.FILES)

if file_form.is_valid():

   file_form = file_form.save(commit=False)

   s3 = boto3.client('s3', region_name=settings.AWS_ZONE,
                           aws_access_key_id=settings.AWS_KEY,
                           aws_secret_access_key=settings.AWS_SECRET)

   file = request.FILES['file']

   if file:

        file_type = file.content_type
        extension = file.name.split(".")[-1]

        # construct file name and location
        filename = calculate_md5(file) + '.'+extension

        # save the file
        try:
             response = s3.upload_fileobj(file, 'bucketname', filename)
        except ClientError as e:
             logging.error(e)
             return False



        file_form.filename = filename
        file_form.dropoff = dropoff
        file_form.save()

Happy for any suggestion.很高兴有任何建议。

calculate_md5 does a read() on the InMemoryFile, which sets the cursor to the end of the file. calculate_md5 对 InMemoryFile 执行 read(),将 cursor 设置为文件末尾。

The right way is to reset the cursor using正确的方法是使用重置 cursor

file.file.seek(0)

and then recall it.然后回忆它。 This will set the cursor to the beginning and the content of the file is available.这会将 cursor 设置为开头并且文件的内容可用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM