2017-10-18 53 views
1

我只是想創建一個REST API來接收文件,處理它並返回一些信息。我的問題是,我正在關注這個示例: http://www.django-rest-framework.org/api-guide/parsers/#fileuploadparserFileUploadParser沒有得到文件名

而且我無法使用郵差或捲曲工作,我想我錯過了一些東西。解析器總是給我兩個錯誤:

  • 的FileUpload解析錯誤 - 沒有上傳處理程序可以處理的數據流
  • 缺少文件名。請求應該包含一個帶有文件名參數的Content-Disposition頭。

這是代碼:

views.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) 

urls.py

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

settings.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/' 

他再次,你可以看到一個郵差捕獲(我已經試過各種):

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 

非常感謝您的幫助

+0

您請求的解析器​​是從郵遞員多聲部的要求,所以你應該使用'MultiPartParser',而不是'FileUploadParser' –

回答

4

Django的REST框架。我們有像Parsers,Renderers和Serializer這樣的組件。

  • 解析器的責任是解析由請求方法發送GET,POST和PUT的數據等在Django REST使用

  • 默認解析器是「JSONParser」。它只解析數據JSON數據[數字,字符串,日期]。它忽略了像FILES這樣的數據。

  • 爲了解析文件,我們需要使用諸如「MultiPartParser」或「FormParser」之類的解析器。

    示例代碼:

    from rest_framework.parsers import MultiPartParser 
        from rest_framework.response import Response 
        from rest_framework.views import APIView 
    
        class ExampleView(APIView): 
         """ 
         A view that can accept POST requests with JSON content. 
         """ 
         parser_classes = (MultiPartParser,) 
    
         def post(self, request, format=None): 
          # to access files 
          print request.FILES 
          # to access data 
          print request.data 
          return Response({'received data': request.data}) 
    

當我們使用屬性request.data然後解析器將解析數據。

參考文獻:Django REST DocsDjango REST Github

+0

隨着你的代碼,這個調用我仍然不'噸收到文件: POST /predict/pabloGrande.jpg HTTP/1.1 主機:127.0.0.1:52276 內容類型:multipart/form-data; border = ---- WebKitFormBoundary7MA4YWxkTrZu0gW ------ WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition:form-data; NAME = 「文件」;文件名= 「pabloGrande.jpg」 內容類型:*/* <./pabloGrande.jpg ------ WebKitFormBoundary7MA4YWxkTrZu0gW –

+0

@PabloCastilla用'request.FILES [ '文件']'訪問它。更新以上答案。請檢查一下。 –

1
在你的意見

。PY改變這樣

parser_classes = (JSONParser, MultiPartParser)

+0

'JSONParser'只適用於'Conteny-Type'頭設置爲'application/json'。不需要使用'JSONParser'。 –