2017-10-18 3 views
1

Je veux juste créer une API REST qui reçoit un fichier, le traite et renvoie des informations. Mon problème est que je suis cet exemple: http://www.django-rest-framework.org/api-guide/parsers/#fileuploadparserFileUploadParser n'obtient pas le nom de fichier

Et je ne peux pas le faire fonctionner en utilisant Postman ou curl, je pense qu'il me manque quelque chose. L'analyseur me donne toujours ces deux erreurs:

  • FileUpload erreur d'analyse - aucun des gestionnaires de téléchargement peut gérer le flux
  • nom de fichier manquant. La requête doit inclure un en-tête Content-Disposition avec un paramètre de nom de fichier.

Voici le code:

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

Il VOus pouvez voir une capture postman (j'ai tout essayé):

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-- 

exigences:

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 

Merci beaucoup pour votre aide

+0

demande Vous avez une demande d'une partie multi de POSTMAN, de sorte que vous devriez utiliser 'MultiPartParser' au lieu de' FileUploadParser' –

Répondre

4

Dans le cadre django REST. nous avons des composants comme des analyseurs, des restitueurs et des sérialiseurs.

  • La responsabilité de Parsers est d'analyser les données qui sont envoyées par des méthodes de demande GET, POST et PUT, etc.

  • analyseur par défaut utilisé dans REST django est 'JSONParser'. Il analyse uniquement les données JSON de données [nombres, chaîne, date]. Il ignore les données comme des fichiers. Afin d'analyser les fichiers, nous devons utiliser des analyseurs syntaxiques tels que "MultiPartParser" ou "FormParser".

    Exemple de code:

    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}) 
    

Lorsque nous utilisons la propriété request.data puis analyseur analyser les données.

Références: Django REST Docs, Django REST Github

+0

Avec votre code et cet appel que je n 'toujours recevoir le fichier: POST /predict/pabloGrande.jpg HTTP/1.1 Hôte: 127.0.0.1:52276 Type de contenu: multipart/form-data; boundary = ---- WebKitFormBoundary7MA4YWxkTrZu0gW ------ WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: données-de-formulaire; nom = "fichier"; filename = "pabloGrande.jpg" Content-Type: */* <./pabloGrande.jpg ------ WebKitFormBoundary7MA4YWxkTrZu0gW –

+0

accès @PabloCastilla avec 'request.FILES [ 'fichier']'. mise à jour ci-dessus réponse. S'il te plaît vérifie le. –

1

dans vos vues.py changer l'analyseur comme celui-ci

parser_classes = (JSONParser, MultiPartParser)

+0

'JSONParser' ne s'applique que si l'en-tête' Conteny-Type' est défini sur 'application/json'. Pas besoin d'utiliser 'JSONParser'. –