0

I am calling the image upload API (Django REST API) from my view in a separate Django project.

My View

if request.method == 'POST' and request.FILES['file']:
    try:
        resp = requests.post(
            "http://19.******/BankImage_API",
            files = {"file" :request.FILES['file']},
            headers={"content-type": "multipart/form-data",
                "Authorization": "Token 71117971*************"
                }, verify=False)

API

class Bankimageapi(APIView):
    def post(self, request):
        if request.method == 'POST' and request.FILES['file']:
            try:
                ........

When I tried to upload an image, I got an error in API where FILES is <MultiValueDict: {}>:

django.utils.datastructures.MultiValueDictKeyError: 'file'

Please guide me to solve this problem.

eigenein
  • 2,083
  • 3
  • 25
  • 43
selvakumar
  • 620
  • 1
  • 8
  • 30
  • once please check key name is 'file' or not in request.FILES['file']... print (request.FILES) then you check it.. – vinodsesetti Feb 13 '19 at 13:48
  • The name is file – selvakumar Feb 13 '19 at 14:12
  • `request.FILES['file']` in your view is a `UploadedFile` (see [here](https://docs.djangoproject.com/en/2.1/ref/files/uploads/#uploaded-files)) and the `requests` library wants you to post the actual content of the file (in binary format). So you should probably `post` this: `request.FILES['file'].read()` or wrap in a `with file.open('rb') as f:` – dirkgroten Feb 13 '19 at 19:15

2 Answers2

1

In your view, the received request.FILES['file'] is an UploadedFile (see docs here), which is a subclass of File.

The requests library wants you to post the binary contents of the file. You can access the contents of the file using (file = request.FILES['file']):

  • read(): files={"file": file.read()}
  • file attribute: files = {"file": file.file} although I'm not sure this will give you control over whether or not this is binary.

Furthermore, you should remove the "content-type" header, which is added automatically by the requests package. This seems to mess up the body of your request.

dirkgroten
  • 20,112
  • 2
  • 29
  • 42
  • when i use this files={"file": file.read()} --> I got empty in FILES – selvakumar Feb 14 '19 at 05:32
  • Ok try the second option then, might need to open the file – dirkgroten Feb 14 '19 at 07:19
  • Sorry Second Option Got error as :I got I/o Operation on closed – selvakumar Feb 14 '19 at 07:22
  • You should wrap the entire call to `requests.post` in the `with open...` – dirkgroten Feb 14 '19 at 07:25
  • I got `raise MultiPartParserError('Invalid boundary in multipart: %s' % boundary.decode()) AttributeError: 'NoneType' object has no attribute 'decode'` using `requests.post` in the `with open...` – selvakumar Feb 14 '19 at 07:31
  • error at api . The file passes from view to api . but the MultiValueDict is empty `FILES ` in api request – selvakumar Feb 14 '19 at 07:40
  • I was able to reproduce your issue. For some reason the payload of the POST request is in the body (check in your API view `request.body`) but not as POST and FILES data. Using `file.read()` and removing the `content-type` header did the trick. – dirkgroten Feb 14 '19 at 10:04
0

What is the id of the input in the html?

Update:

The request.FILES is a dict that references the objects by their id on the html.

Stargazer
  • 1,442
  • 12
  • 19