django - FileUploadParser 没有得到文件名

标签 django django-rest-framework

我只想创建一个接收文件、处理文件并返回一些信息的 REST API。我的问题是我正在遵循这个例子:
http://www.django-rest-framework.org/api-guide/parsers/#fileuploadparser

而且我无法使用 Postman 或 curl 使其工作,我想我错过了一些东西。解析器总是给我这两个错误:

  • FileUpload 解析错误 - 没有任何上传处理程序可以处理流
  • 缺少文件名。请求应包含带有文件名参数的 Content-Disposition header 。

  • 这是代码:

    View .py:
    class FileUploadView(APIView):
        parser_classes = (FileUploadParser,)
    
        def post(self, request, filename, format=None):
            file_obj = request.data['file']
            # ...
            # do some stuff with uploaded file
            # ...
            return Response(status=204)
    
        def put(self, request, filename, format=None):
            file_obj = request.data['file']
            # ...
            # do some stuff with uploaded file
            # ...
            return Response(status=204)
    

    网址.py
    urlpatterns = [
       url(r'predict/(?P<filename>[^/]+)$', app.views.FileUploadView.as_view())
    ]
    

    设置.py
    """
    Django settings for GenderAPI project.
    
    Generated by 'django-admin startproject' using Django 1.9.1.
    
    For more information on this file, see
    https://docs.djangoproject.com/en/1.9/topics/settings/
    
    For the full list of settings and their values, see
    https://docs.djangoproject.com/en/1.9/ref/settings/
    """
    
    import os
    import posixpath
    
    
    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'handlers': {
            'file': {
                'level': 'DEBUG',
                'class': 'logging.FileHandler',
                'filename': 'debug.log',
            },
        },
        'loggers': {
            'django': {
                'handlers': ['file'],
                'level': 'DEBUG',
                'propagate': True,
            },
        },
    }
    
    # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    
    
    # Quick-start development settings - unsuitable for production
    # See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/
    
    # SECURITY WARNING: keep the secret key used in production secret!
    SECRET_KEY = removed
    
    # SECURITY WARNING: don't run with debug turned on in production!
    DEBUG = True
    
    ALLOWED_HOSTS = ['localhost','127.0.0.1']
    
    REST_FRAMEWORK = {
        'DEFAULT_PARSER_CLASSES': (
            'rest_framework.parsers.FileUploadParser'
        )
    }
    
    
    # Application definition
    
    INSTALLED_APPS = [    
    
        # Add your apps here to enable them
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',   
        'rest_framework',
        'app'  
    
    
    ]
    
    MIDDLEWARE = [
    
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware'
    ]
    
    ROOT_URLCONF = 'GenderAPI.urls'
    
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [],
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    
    WSGI_APPLICATION = 'GenderAPI.wsgi.application'
    
    # Database
    # https://docs.djangoproject.com/en/1.9/ref/settings/#databases
    
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }
    
    # Static files (CSS, JavaScript, Images)
    # https://docs.djangoproject.com/en/1.9/howto/static-files/
    
    STATIC_URL = '/static/'
    STATIC_ROOT = posixpath.join(*(BASE_DIR.split(os.path.sep) + ['static']))
    
    FILE_UPLOAD_TEMP_DIR = BASE_DIR
    MEDIA_URL  = '/media/'
    

    在这里你可以看到 postman 捕获(我已经尝试了一切):
    PUT /predict/pabloGrande.jpg HTTP/1.1
    Host: 127.0.0.1:52276
    Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
    
    ------WebKitFormBoundary7MA4YWxkTrZu0gW
    Content-Disposition: form-data; name="file"; filename="04320cf.jpg"
    Content-Type: image/jpeg
    
    
    ------WebKitFormBoundary7MA4YWxkTrZu0gW--
    

    要求:
    bleach==1.5.0
    Django==1.11.6
    djangorestframework==3.7.1
    html5lib==0.9999999
    Markdown==2.6.9
    numpy==1.13.3
    olefile==0.44
    pandas==0.20.3
    Pillow==4.3.0
    pip==9.0.1
    protobuf==3.4.0
    python-dateutil==2.6.1
    pytz==2017.2
    scipy==1.0.0rc1
    setuptools==28.8.0
    six==1.11.0
    tensorflow==1.3.0
    tensorflow-tensorboard==0.1.8
    Werkzeug==0.12.2
    wheel==0.30.0
    

    非常感谢你的帮助

    最佳答案

    您不需要使用 MultipartParserFormParser .

    您需要的是带有 FileField() 的序列化程序像这样:

    序列化程序.py:

    class FileUploadSerializer(serializers.Serializer):
        # I set use_url to False so I don't need to pass file 
        # through the url itself - defaults to True if you need it
        file = serializers.FileField(use_url=False)
    

    那么当你尝试访问 file在下面,您将拥有一个带有名为 file 的键的 dict .就个人而言,我可能会将其命名为比"file"更具描述性的名称,但这取决于您。
    from .serializers import FileUploadSerializer
    
        class FileUploadView(APIView):
    
           def post(self, request):
               # set 'data' so that you can use 'is_vaid()' and raise exception
               # if the file fails validation
               serializer = FileUploadSerializer(data=request.data)
               serializer.is_valid(raise_exception=True)
               # once validated, grab the file from the request itself
               file = request.FILES['file']
    

    关于django - FileUploadParser 没有得到文件名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46806335/

    相关文章:

    django - DecimalField 充当默认值 0.00 的浮点字段?

    python - 如何在 Django Rest Framework 中将数组序列化为字符串?

    python - Django Registration Redux 自定义注册表单

    python - 如何使用 Python elasticsearch_dsl 在分析器中包含 shingle elasticsearch 过滤器

    django - 使用 Django 构建搜索引擎的建议

    Django-rest-framework 从 id 更新外键

    Django 迁移不会更新我的数据库

    python - select_related : ' ' . 中给出的非关系字段选项是:(无)

    rest - REST 应用程序的后端异常处理 - 我们应该返回 4XX 错误还是带有错误标记的 200

    python - 在 Django REST Framework 中显示嵌套实体