93

I am trying to POST data to my API. I have a model with an image field where:

image = models.ImageField()

I have an image on my local box, which I am trying to send. Am I sending it correctly?

{
   "id": "3", 
   "uid":"273a0d69",
   "uuid": "90",
   "image": "@/home/user/Downloads/tt.jpeg"
}
User_Targaryen
  • 4,125
  • 4
  • 30
  • 51

7 Answers7

182

That's not how you send file on postman. What you did is sending a string which is the path of your image, nothing more.

What you should do is:

  1. After setting request method to POST, click to the 'body' tab.
  2. Select form-data. At first line, you'll see text boxes named key and value. Write 'image' to the key. You'll see value type which is set to 'text' as default. Make it File and upload your file.
  3. Then select 'raw' and paste your JSON file. Also, just next to the binary choice, you'll see 'Text' is clicked. Make it JSON.

form-data section

raw section

You're ready to go.

In your Django view,

from rest_framework.views import APIView
from rest_framework.parsers import MultiPartParser
from rest_framework.decorators import parser_classes

@parser_classes((MultiPartParser, ))
class UploadFileAndJson(APIView):

    def post(self, request, format=None):
        thumbnail = request.FILES["file"]
        info = json.loads(request.data['info'])
        ...
        return HttpResponse()
meJustAndrew
  • 6,011
  • 8
  • 50
  • 76
Cagatay Barin
  • 3,428
  • 2
  • 24
  • 43
  • 2
    Hello is there a way to do nested images, i.e. { model: { image: file } } – Babbz77 Oct 05 '17 at 01:34
  • 1
    I get a `"detail": "Unsupported media type \"application/json\" in request."` with a 415 HTTP status code. Any idea? – MarAja Mar 10 '18 at 14:36
  • Can you add this to headers and try again? key:Content-Type value:application/json – Cagatay Barin Mar 10 '18 at 14:40
  • 3
    I think when you select application/json in Postman, it automatically sets the right header but if I type it in manually it does not work either. Actually it seems I get only the image or the json on the server side depending on the radio box button I selected. Not both. – MarAja Mar 10 '18 at 15:04
  • 5
    Ok I got it, if you want to apply the above solution, you should enter the JSON in the `form-data` as a key/value. The radio button shows that you can't send both `form-data` and `raw-data`. – MarAja Mar 10 '18 at 15:08
  • Yes, check my answer. – MarAja Mar 10 '18 at 15:13
  • This even worked for my Rails project. Postman delivers again. – DaveWoodall.com Dec 26 '18 at 01:23
37

Now you can hover the key input and select "file", which will give you a file selector in the value column:

enter image description here

theisof
  • 671
  • 6
  • 6
17

The accepted answer works if you set the JSON as a key/value pair in the form-data panel (See the image hereunder)

enter image description here

Nevertheless, I am wondering if it is a very clean way to design an API. If it is mandatory for you to upload both image and JSON in a single call maybe it is ok but if you could separate the routes (one for image uploading, the other for JSON body with a proper content-type header), it seems better.

MarAja
  • 1,547
  • 4
  • 20
  • 36
  • It did not work for me. I tried the same way.... but I have a requirement to save a file in the server with filename as a parameter. Any suggestion ... will be highly appreciated. – Ishwor Khanal May 16 '18 at 10:23
  • You don't have to give any header for this. Just make sure you are accessing file and data correctly in your view. – Jatin Goyal Nov 14 '19 at 07:07
14

It can be done in three ways

1. Go to Body > Form-data > Select Files in the column

enter image description here

2. Go to Body > binary > Select File

enter image description here

3. Encode image to base64 string and pass it through postman Body > raw > JSON like mentioned in the attached screenshots

enter image description here

enter image description here

Then on the server-side, you can decode it that way

import base64
decode = base64.b64decode(data)

from django.core.files.base import ContentFile
file = ContentFile(decode, name=name)

Note: You could encode the file to base64 through that link and send it in the curl.

https://base64.guru/converter/encode/file

Umar Asghar
  • 3,808
  • 1
  • 36
  • 32
  • Extra info: Make sure you allow Postman to access the directory where you uploading the file from; Or upload a file from the directory where Postman has access to. In Mac is at: `/postman/files`. – Cristea Apr 03 '22 at 15:14
  • @Umar, can this image be accessed from other computer? Or other person in my team? – Maaza Apr 26 '23 at 20:54
7

It works for me:

  1. Goto Body
  2. Form-data
  3. Chose "File" in the first cell enter image description hereproperties
swor
  • 751
  • 3
  • 8
  • 21
1

Follow the below steps:

  1. No need to give any type of header.
  2. Select body > form-data and do same as shown in the image. 1

  3. Now in your Django view.py

def post(self, request, *args, **kwargs):
    image = request.FILES["image"]
    data = json.loads(request.data['data'])
    ...
    return Response(...)
  1. You can access all the keys (id, uid etc..) from the data variable.
Jatin Goyal
  • 487
  • 1
  • 4
  • 11
  • Just to clarify - the "image" key is the name of the file input field. So if you have then your key in Postman would be myImageFile. – CodeCaptain Nov 21 '19 at 22:51
  • @CodeCaptain, I have tested it on my system and the answer is perfectly fine. The "image" is the key name and same would be for Postman. – Jatin Goyal Nov 22 '19 at 06:03
  • Your answer is correct. I was simply pointing out that if someone has a file input that is not named "image" it would not work. My file input field name was "imageFile" so it was not working for me in Postman. Then I realized that "image" is not the type of file, in this case, it is the actual name of the file input field. Just want to save the next person a few minutes. – CodeCaptain Nov 22 '19 at 09:13
  • @CodeCaptain Okay :) – Jatin Goyal Nov 22 '19 at 10:20
1

You can upload your image from the binary tab if the endpoint is expecting just an image (not a key-value pair). enter image description here

Kirill
  • 738
  • 10
  • 26