18

I'm trying to do a POST using curl:

curl --dump-header - -H "Content-Type: application/json" -X POST --data '{"item_id": "1"}' http://www.mylocal.com:8000/api/1/bookmarks/

However, request.POST is always empty.

Below is my ModelResource code:

class BookmarkResource(ModelResource):


    class Meta:
        queryset = Bookmark.objects.all()    
        resource_name = 'bookmarks'
        fields = ['id', 'tags']
        allowed_methods = ['get', 'post', 'delete', 'put']
        always_return_data = True
        authorization= Authorization()
        include_resource_uri = False

    def determine_format(self, request):
        return "application/json"

    def obj_create(self, bundle, **kwargs):

        request = bundle.request

        try:
            payload = simplejson.loads(request.POST.keys()[0])
        except:
            payload = simplejson.loads(request.POST.keys())

Anybody knows what I'm missing?

Thanks in advance.

dannyroa
  • 5,501
  • 6
  • 41
  • 59

2 Answers2

67

Starting at Django 1.5, request.POST does not contain non-form data anymore. They are now in request.body.

https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.POST

Ivar
  • 6,138
  • 12
  • 49
  • 61
dannyroa
  • 5,501
  • 6
  • 41
  • 59
  • See also http://stackoverflow.com/questions/1208067/wheres-my-json-data-in-my-incoming-django-request. – Seth Mar 11 '14 at 00:25
  • 2
    @dannyroa What differentiates "form data" and "non-form data"? – rrauenza Aug 11 '16 at 20:46
  • 1
    ...Looking at Django source, it looks like it is defined in `_load_post_and_files()` and depends on the `CONTENT_TYPE` -- `multipart/form-data` and `application/x-www-form-urlencoded` – rrauenza Aug 11 '16 at 20:55
1

I'm not a cURL expect but copying a POST request out of Chrome dev tools my --data looked as follows:

--data "foo=bar&bar=foo"

So it looks like you might want to change your command to:

--data item_id="1"

Side note: I can highly recommend either of the following Chrome apps for making HTTP requests:

Advanced REST client OR Dev HTTP Client

Additionally if you can make the call in a browser (form submit or such like) then in Chrome dev tools network panel you can copy the request as a cURL command (right click on it)

rockingskier
  • 9,066
  • 3
  • 40
  • 49
  • Have you tried pdb/ipdb to see what is available on `request`? – rockingskier Apr 25 '13 at 12:50
  • Yeah, I used ipdb to trace through it. On the REST Client, I set the Content-Type to "application/json". – dannyroa Apr 25 '13 at 12:51
  • Weird thing is sometimes it goes to request.GET. I made sure I was doing a POST. – dannyroa Apr 25 '13 at 12:53
  • `'{"item_id": "1"}'` is available on bundle.request.body if that helps. Will keep digging. – rockingskier Apr 25 '13 at 13:05
  • You are right. Is this something that changed recently for Django on how it handles request? – dannyroa Apr 25 '13 at 13:09
  • Looks like this is a change related to Django 1.5. request.POST does not contain non-form data anymore. https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.POST – dannyroa Apr 25 '13 at 13:13
  • Ahh good catch. Also if you're simply mapping json to the model then you don't need to create a `obj_create` method. – rockingskier Apr 25 '13 at 13:18
  • Actually, I had to override the create method. I get an item_id and access another API before creating the object. – dannyroa Apr 25 '13 at 13:23