Configuración de Angular en proyecto Django

imagen / Pythonízame
  
25 de Septiembre de 2015   1  

Hace algunos días realicé una publicación que explicaba cómo realizar peticiones AJAX de servicios web Django utilizando Jquery y explicabamos la importancia de incluir la variable "X-CSRFToken" en el header de cada solicitud, hoy les compartiré algo similar pero utilizando AngularJS. 

Al trabajar con estas dos tecnologías (Django y AngularJS) siempre tenemos que tener en cuenta lo siguiente:

 

  1. La forma por defecto que trabajan en el template son utilizando los simbolos "{{ mivariable }}", causando un conflicto bastante estresante.
  2. Las solicitudes AJAX por ejemplo POST requieren que se incluya el token de verificación.
  3. Los datos mandados por AngularJS en formato JSON no son legibles por el Backend (este último es un dolor de cabeza).

Tal vez existan otros más, sin embargo estos 3 puntos fueron para mí un sufrimiento cuando empecé a utilizar AngularJS, sin embargo leyendo documentación oficial de ambas tecnologías y tambien gracias a la gran universidad StackOverflow pude resolver cada una de ellas y realizar un GIST que está alojado en mi Github y que utilizo en todos mis proyectos Angular con Django.

Lo que tenemos que hacer es agregar algo de código en nuestra función de configuración de nuestra aplicación Angular.

 

Paso 1. Configurar los simbolos del template, en pocas palabras cambiar los simbolos "{{ }}" por "[[ ]]" o como se nos facilite. En mi caso configuré "[[ ]]"

//configuramos los símbolos
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');

Otra recomendación para obtener compatibilidad con las etiquetas AngularJS es el uso de las famosas tags Verbatim, la función de esta etiqueta de bloque es detener el motor de plantilla de django para que puedas utilizar algunas etiquetas parecidas a las de Django "{{ }}".

Estas etiquetas se utilizan de esta manera : 

{% verbatim %}
    {{ variableAngular }} <!-- No existe conflicto  -->
{% endverbatim %}

 

Paso 2. Configuramos el CSRFTOKEN para las peticiones por AJAX

//configuramos el CSRFTOKEN para las peticiones con ANGULARJS
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
$httpProvider.defaults.withCredentials = true;
$httpProvider.defaults.cache=true;
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';


Paso 3. Realizar una función para la compatibilidad de transmisión de datos JSON por POST y sobre escribir el $httpProvider para enviar datos que primero pasarán por dicha función.

//función para compatibilidad de transmisión de datos JSON por POST
var param = function(obj) {
var query = '', name, value, fullSubName, subName, subValue, innerObj, i;
for(name in obj) {
value = obj[name];
if(value instanceof Array) {
    for(i=0; i<value.length; ++i) {
    subValue = value[i];
    fullSubName = name + '[' + i + ']';
    innerObj = {};
    innerObj[fullSubName] = subValue;
    query += param(innerObj) + '&';
    }
}
else if(value instanceof Object) {
     for(subName in value) {
     subValue = value[subName];
     fullSubName = name + '[' + subName + ']';
     innerObj = {};
     innerObj[fullSubName] = subValue;
     query += param(innerObj) + '&';
     }
}
else if(value !== undefined && value !== null)
     query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
}
     return query.length ? query.substr(0, query.length - 1) : query;
};


// Override $http service's default transformRequest
$httpProvider.defaults.transformRequest = [function(data) {
    return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data;
}];

 

Con esta configuración estaríamos atacando los puntos de arriba para poder trabajar de manera transparente con AngularJS en proyectos Django. 

Su código de configuración debe de quedar mas o menos así:

 

El código del GIST lo pueden descargar aquí, es libre de uso y les facilitará totalmente la vida :)



Gaspar Dzul

Desarrollador Front End y Móvil.