Django & TastyPie: request.POST is empty
Asked Answered
S

2

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.

Sycamore answered 25/4, 2013 at 11:17 Comment(0)
S
69

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

Sycamore answered 25/4, 2013 at 13:30 Comment(3)
See also #1208567.Nonmoral
@Sycamore What differentiates "form data" and "non-form data"?Imagine
...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-urlencodedImagine
C
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)

Carboy answered 25/4, 2013 at 12:4 Comment(8)
Have you tried pdb/ipdb to see what is available on request?Carboy
Yeah, I used ipdb to trace through it. On the REST Client, I set the Content-Type to "application/json".Sycamore
Weird thing is sometimes it goes to request.GET. I made sure I was doing a POST.Sycamore
'{"item_id": "1"}' is available on bundle.request.body if that helps. Will keep digging.Carboy
You are right. Is this something that changed recently for Django on how it handles request?Sycamore
Looks like this is a change related to Django 1.5. request.POST does not contain non-form data anymore. docs.djangoproject.com/en/dev/ref/request-response/…Sycamore
Ahh good catch. Also if you're simply mapping json to the model then you don't need to create a obj_create method.Carboy
Actually, I had to override the create method. I get an item_id and access another API before creating the object.Sycamore

© 2022 - 2024 — McMap. All rights reserved.