Pruebas unitarias Django JSON Ver

Estoy tratando de escribir algunas pruebas unitarias para algunas vistas json_view de Django y tengo problemas para pasar el json_string a la vista. Ayer publiqué una pregunta relacionada acerca de pasar una cadena json a una vista de Django desde JS, el problema era que en mi JS solo estaba pasando la cadena json donde tenía que pasar la cadena como el atributo de un objeto, porque si esto no se hacía, se tomaba la cadena como la clave para el dictado de la consulta resultante. Estoy teniendo un problema similar otra vez, excepto que esta vez es una prueba de unidad de Django para la Vista de Django. Aquí hay una versión simplificada de mi código que produce el mismo resultado.

class MyTestCase(TestCase): def setUp(self): self.u = User.objects.create_user('test','test','test') self.u.is_active = True self.u.save() self.client.login(username='test',password='test') def test_create_object_from_form(self): """Test the creation of the Instance from the form data.""" import json json_string json.dumps({'resource':{'type':'book','author':'John Doe'}}) print(json_string) response = self.client.post(reverse('ajax_view'), {'form':json_string},'json') self.assetNotContains(response,'error') 

y la vista se ve así

 @json_view def ajax_view(request): """Process the incoming form data.""" if request.method == 'POST': print(request.POST) form_data = json.loads(request.POST['form']) resource_data = form_data['resource'] form = MyUserForm(resource_data) if form.is_valid(): ... 

Esto es lo que producen las dos declaraciones impresas cuando se ejecuta la prueba. El json_string es

 {"resource": {"type": "book", "author": "John Doe"}} 

y el dictamen de consulta parece

  

Soy un novato total con JS y ajax, así que no te preocupes por herir mi orgullo, la respuesta es probablemente tan cerca que podría saltar y morderme.

Edición final

Originalmente dije que el encabezado HTTP_X_REQUESTED_WITH='XMLHttpRequest' era necesario en la llamada posterior, pero actualmente es falso mientras se realiza la prueba. Este encabezado es necesario para el middleware csrf pero csrf está deshabilitado en las pruebas. Sin embargo, sigo creyendo que es una buena práctica poner a prueba incluso si el middleware deshabilita csrf ya que la mayoría de las bibliotecas de javascript ya pasan este encabezado de forma predeterminada al hacer ajax. Además, si otra parte del código que no está deshabilitado utiliza el método is_ajax, no necesitará depurar su unidad de prueba durante horas para descubrir que faltaba el encabezado.

El problema es con el tipo de contenido porque cuando django obtiene un valor que es diferente a text/html , no usa el manejo de datos de publicación predeterminado, que consiste en formatear sus datos como en una consulta: type=book&author=JohnDoe por ejemplo.

Entonces el código fijo es:

 response = self.client.post(reverse('ajax_view'), {'form':json_string}, HTTP_X_REQUESTED_WITH='XMLHttpRequest') 

Así es como lo estoy usando yo mismo:

 post_data = { "jsonrpc" : "2.0", "method": method, "params" : params, "id" : id } return client.post('/api/json/', json.dumps(post_data), "text/json", HTTP_X_REQUESTED_WITH='XMLHttpRequest') 

para hacer algunos json-rpc. Tenga en cuenta que, dado que paso un tipo de contenido diferente al valor predeterminado, mis datos se pasan como están en la solicitud posterior.

Gracias a @Eric_Fortin por activarme en el encabezado, sin embargo, no resuelve mi problema con el diccionario de consultas mal formado utilizando ‘client.post’. Una vez que hice el cambio de POST a GET con el encabezado XMLHttpRequest mi diccionario de consultas se endureció. Aquí está la solución actual:

 response = self.client.get(reverse('ajax_view'), {'form':json_string},'json', HTTP_X_REQUESTED_WITH='XMLHttpRequest') 

esta es solo una respuesta parcial, ya que esta solicitud cambiará los datos en el servidor y debe ser POST no un GET.

Editar:

Aquí está el código final en mi prueba que funciona para pasar una cadena JSON a través de POST a mi vista:

 response = self.client.post(reverse('ajax_view'), {'form':json.dumps(json_dict)}) 

Ahora, imprimir desde la vista muestra que el diccionario de consultas está bien formado.

  

Encontré la respuesta mientras jugueteaba con uno de mis compañeros de trabajo, al eliminar el tipo de contenido ‘json’ se corrigió el diccionario de consultas mal formado. La vista que se está probando no hace uso o llama a ‘HttpRequest.is_ajax ()’, el envío del encabezado XMLHttpRequest ‘no tiene ningún impacto en mi problema, aunque incluir el encabezado constituiría una buena forma ya que esta publicación es una solicitud ajax .