[Django]-Sending JSON using the django test client

98👍

@mrmagooey is right

def test_your_test(self):
    python_dict = {
        "1": {
            "guid": "8a40135230f21bdb0130f21c255c0007",
            "portalId": 999,
            "email": "fake@email"
        }
    }
    response = self.client.post('/pipeline-endpoint/',
                                json.dumps(python_dict),
                                content_type="application/json")

use json.dumps instead of json.loads

23👍

rest_framework‘s APIClient (which is the the default client_class in APITestCase) takes care of dumping dict to JSON and it sets proper content type by passing format='json'.

from rest_framework import status
from rest_framework.test import APIClient, APITestCase


class MyTestCase(APITestCase):
    url = '/url'

    def post(self, payload, url=None):
        """
        Helper to send an HTTP post.

        @param (dict) payload: request body

        @returns: response
        """
        if url is None:
            url = self.url

        return self.client.post(url, payload, format='json')

    def test_my_function(self):
        payload = {
            'key': 'value'
        }
        response = self.post(payload)
        self.assertEqual(response.status_code, status.HTTP_200_OK)

22👍

Try:

 self.client.generic('POST', '/url', json.dumps({'json': 'object'})

15👍

You can always use the HttpRequest.body which loads the raw request data. This way you can handle your own data processing.

c = Client()
json_str= json.dumps({"data": {"id": 1}})
c.post('/ajax/handler/', data= json_str, content_type='application/json',
                                         HTTP_X_REQUESTED_WITH='XMLHttpRequest')


def index(request):
    ....
    print json.loads(request.body)

10👍

Since Django 3.0 you can just add content_type='application/json' and pass your data as Python dictionary.

From Django documentation (section Making requests):

If you provide content_type as application/json, the data is
serialized using json.dumps() if it’s a dict, list, or tuple.
Serialization is performed with DjangoJSONEncoder by default, and can
be overridden by providing a json_encoder argument to Client. This
serialization also happens for put(), patch(), and delete() requests.

response = client.post(
    f'/customer/{customer.id}/edit',
    {'email': new_email},
    content_type='application/json'
)

2👍

You can user iteritems on dictionaries to loop

for index, p in prospects_json.iteritems():
  prospect={
    'email': p['email'],
  }

or alternatively

for index in prospect_json:
  prospect={
    'email': prospect_json[ index ]['email']
  }

1👍

Adding to Guillaume Vincent’s answer, from Django 2.1 we no longer need to use json.dumps for passing the data.

Changed in Django 2.1:
The JSON serialization described above was added. In older versions, you can call json.dumps() on data before passing it to post() to achieve the same thing.

Leave a comment