Question

I'm using a simple REST client to test. Sending a simple JPEG, tried the following content-Type(s): Content-Type: image/jpeg Content-Type: multipart/form-data

Also note csrftoken authentication is turned off to allow outside 3rd party REST connection.

(image is attached via the rest client) Checked wireshark and the packet is setup according to the above parameter.

Django - request object has several variables: request.body request.FILES

After the POST is received by the Django server, the request object always stores all data/payload into request.body. Shouldn't an image or any attached files be going into request.FILES? Is there something setup incorrectly on the content-type or POST.

very simple code. Just trying to print into the log. All objects in post keep going to request.body

def testPost(request):
     print request.body
     print request.FILES
     return HttpResponse()

Wireshark packet:

Hypertext Transfer Protocol
POST /testPost/ HTTP/1.1\r\n
Host: MYURL.com:8000\r\n
Connection: keep-alive\r\n
Content-Length: 8318\r\n
Origin: chrome-extension://aejoelaoggembcahagimdiliamlcdmfm\r\n
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36\r\n
Content-Type: image/jpeg\r\n
Accept: */*\r\n
Accept-Encoding: gzip,deflate,sdch\r\n
Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4\r\n
Cookie: ******; csrftoken=**********\r\n
\r\n
[Full request URI: http://MYURL.com:8000/testPost/]
[HTTP request 1/1]

JPEG File Interchange Format

Was it helpful?

Solution

Here is how I handle file uploads: which in this case happen to be images. One of the issues I fought with for awhile was that request.FILES could come in with multiple keys and I always wanted the last one.

Note: request.FILES will only contain data if:

  1. the request is a POST
  2. the request has the attribute 'enctype="multipart/form-data"'

see the Django File-uploads documentation for more details.

The Model: First there is a model with a ImageField in it: models.py

photos_dir = settings.MEDIA_ROOT + "/photos" + "/%Y/%m/%d/"

class Photo(models.Model):
   image    = models.ImageField(upload_to=photos_dir, null=True, blank=True, default=None)
   filename = models.CharField(max_length=60, blank=True, null=True)

The View: in views.py handle the post:

from django.core.files.images import ImageFile

def upload_image( request ):

   file_key=None
   for file_key in sorted(request.FILES):
      pass

   wrapped_file = ImageFile(request.FILES[file_key])
   filename = wrapped_file.name

   # new photo table-row 
   photo = Photo()
   photo.filename = filename
   photo.image = request.FILES[file_key]

   try:
      photo.save()
   except OSError:
      print "Deal with this situation"

   # do your stuff here.
   return HttpResponse("boo", "text/html");

The Standlone Poster: Some python code to stimulate your django view.

Reference: I actually used this lib: poster.encode to 'stimulate data' to my django view.py

from poster.streaminghttp import register_openers
from poster.encode import multipart_encode
import urllib2

server = "http://localhost/"
headers = {}

# Register the streaming http handlers with urllib2
register_openers()

img="path/to/image/image.png"

data = {'media' : open( img ),
        'additionalattr': 111,
}
datagen, headers = multipart_encode(data)

headers['Connection']='keep-alive'
request = urllib2.Request('%s/upload_image/' % ( server ), datagen, headers)

print urllib2.urlopen(request).read() 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top