25

I have a django application with several views that accept json objects via POST requests. The json objects are medium-complex with a few layers of nesting, so I'm using the json library to parse raw_post_data, as shown here:

def handle_ajax_call(request):
    post_json = json.loads(request.raw_post_data)

    ... (do stuff with json query)

Next, I want to write tests for these views. Unfortunately, I can't figure out how to pass the json object to the Client. Here's a simplest-case version of my code:

def test_ajax_call(self):
    c = Client()
    call_command('loadfixtures', 'temp-fixtures-1') #Custom command to populate the DB

    J = {
      some_info : {
        attr1 : "AAAA",
        attr2 : "BBBB",
        list_attr : [ "x", "y", "z" ]
      },
      more_info : { ... },
      info_list : [ 1, 22, 23, 24, 5, 26, 7 ]
    }

    J_string = json.dumps(J)
    response = c.post('/ajax/call/', data=J_string )

When I run the test, it fails with:

AttributeError: 'str' object has no attribute 'items'

How can I pass the JSON object in the Client.post method?

1 Answer 1

54

The documentation seems to imply that if you pass a content_type parameter to client.post, it will treat the data value as a document and POST it directly. So try this:

response = c.post('/ajax/call/', content_type='application/json', data=J_string)
Sign up to request clarification or add additional context in comments.

5 Comments

Awesome! Thanks for decoding the fine print in the documentation. It never mentions json specifically, so it wasn't turning up in any of my searches.
Note that for this particular use case, the request.is_ajax() probably doesn't work. So if you are using something like 'application/json' in request.META['CONTENT_TYPE'] to detect if the call is Ajax instead, Daniel's solution has the added benefit of properly setting the content type header.
This is the post info I receive when adding that content type: <QueryDict: {u'{"info_list": [1, 22, 23, 24, 5, 26, 7], "some_info": {"list_attr": ["x", "y", "z"], "attr2": "BBBB", "attr1": "AAAA"}}': [u'']}>, so all the data becomes the key, that doesn't seems right.
@Hassek you must not have dumped a json string like the question above. I was getting same issue until I did a json.dumps(data)
@Abe did you manage to test your ajax view? i.e. your were able to retrieve data post from client in your view? I have open a post for an issue testing my ajax view so I would appreciate your kind help...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.