简体   繁体   English

django s3 boto文件上传TypeError:文件无效:

[英]django s3 boto file upload TypeError: invalid file: <InMemoryUploadedFile:

I am trying to upload a file from postman to s3 and getting error on k.set_contents_from_filename(file) TypeError: invalid file: Can you please take look? 我试图将文件从邮递员上传到s3并在k.set_contents_from_filename(文件)上获取错误TypeError:无效文件:你能看看吗? Thanks a lot. 非常感谢。

serializers.py serializers.py

from rest_framework import serializers
class ResourceSerializer(serializers.Serializer):
    file = serializers.FileField(required=True, max_length=None, use_url=True)
    name = serializers.CharField(required=True, max_length=500)

views.py views.py

import logging
from boto.s3.key import Key

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

from .serializers import ResourceSerializer
from .utils import create_boto_connection
from django.conf import settings


class Resource(APIView):
    def post(self, request, format=None):
        serializer = ResourceSerializer(data=request.data)
        if serializer.is_valid():
            context = {}
            file = serializer.validated_data['file']
            name = serializer.validated_data['name']
            ext = file.name.split('.')[-1]
            new_file_name = '{file}.{ext}'.format(file=name, ext=ext)
            file_name_with_dir = 'profile_photos/{}'.format(new_file_name)
            # Create s3boto connection
            conn = create_boto_connection()
            try:
                bucket = conn.get_bucket(settings.AWS_STORAGE_BUCKET_NAME)
                k = Key(bucket)
                k.key = file_name_with_dir
                k.set_contents_from_filename(file)
                k.make_public()
                context['file'] = new_file_name
            except Exception as e:
                context['message'] = 'Failed to process request'
                # Logging Exceptions
                logging.exception(e)
                logging.debug("Could not upload to S3")
            return Response(context, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

utils.py utils.py

from boto.s3.connection import S3Connection

from django.conf import settings


def create_boto_connection():
    conn = S3Connection(settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY)
    # conn = boto.connect_s3()
    return conn

urls.py urls.py

from django.conf.urls import url

from s3boto import views

urlpatterns = [
    # v1
    url(r'^v1/s3boto/upload-resource/$', views.Resource.as_view(), name="upload-resource"),
]

postman: 邮差: 在此输入图像描述

You are passing a django InMemoryUploadedFile to the method set_content_from_filename , which expects a string. 您正在将django InMemoryUploadedFile传递给方法set_content_from_filename ,该方法需要一个字符串。

From the boto documentation : boto文档

set_contents_from_filename (filename, headers=None, replace=True, cb=None, num_cb=10, policy=None, md5=None, reduced_redundancy=False, encrypt_key=False) set_contents_from_filename (filename,headers = None,replace = True,cb = None,num_cb = 10,policy = None,md5 = None,reduced_redundancy = False,encrypt_key = False)

Store an object in S3 using the name of the Key object as the key in S3 and the contents of the file named by 'filename'. 使用Key对象的名称作为S3中的键以及由'filename'命名的文件的内容,在S3中存储对象。 See set_contents_from_file method for details about the parameters. 有关参数的详细信息,请参阅set_contents_from_file方法。

Either use set_content_from_file or save the file to a local temporary file and pass that filename to set_content_from_filename . 使用set_content_from_file或将文件保存到本地临时文件,并将该文件名传递给set_content_from_filename

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

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