2009-11-25 11 views
22

En mi proyecto tengo muchos métodos Ajax, con scripts externos del lado del cliente (¡No quiero incluir JavaScript en las plantillas!) Y cambiar URLs es un poco doloroso para mí porque Necesito cambiar las URL en mis llamadas Ajax de forma manual.Django reverse() para JavaScript

¿Hay alguna manera de emular el comportamiento de {% url %} templatetag en JavaScript?

Por ejemplo, imprimir los patrones de url que comiencen con ^ajax y más tarde en scripts reemplazar patrones con sus valores reales?

Eso es lo que tengo en mente, y mi pregunta es: ¿hay alguna práctica común para hacer cosas como esa? Tal vez algunas aplicaciones reutilizables? También me complacerá leer los consejos y pensamientos relevantes que tenga.

Actualización 1: estoy hablando de URL computadas, no los estáticas:

url(r'^ajax/delete/(?P<type>image|audio)/(?P<item_id>\d+)/from/set/(?P<set_id>\d+)/$', 'blog.ajax.remove_item_from_set'), 

Respuesta

10

https://github.com/mlouro/django-js-utils

dutils es una biblioteca pequeña utilidad que tiene como objetivo proporcionar a los desarrolladores de JavaScript/Django con algunas empresas de servicios públicos que ayuden al desarrollo de RIA en la parte superior de un Django backend.

Actualmente soporta las siguientes características:

  • método inversa para generar URLs Django ...
+0

También echa un vistazo a algunas de las horquillas. Dimitri-Gnidash construye las URL con un comando de gestión. ljosa creó una vista que los construye sobre la marcha. – SystemParadox

+0

Parece que esta solución aún requiere codificar el diccionario {url_name: pattern}. sería bueno automatizar la generación de la lista encontrada en dutils.conf.urls.example.js ??? – Fydo

+0

@Fydo utilícelo https://github.com/ierror/django-js-reverse –

4

Lo que suelo hacer es poner la URL, ya sea en un elemento <input type="hidden" />, o en el atributo rel="".

Entonces, al escribir la JS (usando jQuery abajo) yo:

$('div#show_more').click(function() { 
    var url = $(this).attr('rel'); 
    // or 
    var url = $('#more_url').val(); 

    $.get(url, function() { /* ... */ }); 
}); 

atributos no estándar están bien soportado por todos los navegadores y elementos ocultos no tienen que estar en formas.

+0

Qué haría usted con URLs calculadas? url (r '^ ajax/delete/(? P imagen | audio)/(? P \ d +)/from/set/(? P \ d +)/$', 'blog.ajax.remove_item_from_set') , – dir01

+0

Los pones en algún lugar de la página (en la plantilla de django) - el javascript es un archivo separado que no es generado por django. –

14

¿Qué hay de malo en poner JavaScript en sus plantillas?

A menudo, en cualquier caso, desea llamar a una función de inicialización en su plantilla HTML, así que ¿por qué no pasarle un objeto que contiene las URL que va a utilizar?

<script> 
MYGLOBAL.mymodule.init({ 
    fancy_ajax_url: '{% url fancy %}', 
    fancier_ajax_url: '{% url fancier %}' 
}); 
</script> 

Si usted se encuentra pasando una gran cantidad de variables de esta manera, o el deseo de usar la lógica en su JavaScript que lo hace en sus plantillas HTML, entonces ¿por qué no hacer que la secuencia de comandos a través de sistema de plantillas de Django? Recuerde, las plantillas de Django no son solo para documentos HTML, a menudo ayuda usar plantillas para texto sin formato, XML, JSON y sí, incluso JavaScript. ¿Preocupado por el rendimiento? Luego, almacena el resultado en caché.

+0

Estas son las iniciales de mi tarea, así que enfréntala) Los archivos JS se entregarían a través de CDN. Lo que puedo hacer es poner los patrones url en la parte superior de la página (establecer las variables js) y compilar las direcciones URL reales de las expresiones regulares con datos reales – dir01

+3

La desventaja de este enfoque es que no hay forma de usar los argumentos de vista. – intgr

+0

Por diseño, mezclar idiomas es una mala idea. – azmeuk

16

intente crear javascript funciones de ayuda (en plantillas de Django) para generar cadena URL. En forma simple, podrían verse así:

function generete_some_url(id){ 
    return "{% url some_url itemid=112233 %}".replace("112233", id); 
} 

Quizás esto tenga algunas otras implicaciones, pero creo que debería funcionar.

+0

¡Usted me salvó la vida, gracias! Solo una observación, supongo que es mejor usar id = 0 en el marcador de posición porque nunca tendrá uno igual a 0, no podríamos decir lo mismo para 112233, pero en el otro puede haber cambiado todos los 0, tal vez deberíamos una plantilla para cambiar en la posición correcta. –

+0

Me complace que le guste mi solución. Con respecto a la identificación, es más importante que el valor que está reemplazando no esté en otra parte en la cadena url. Entonces, realmente no se mide, es 0 o 112233 en la medida en que el mismo valor no esté en otra parte en la cadena url. – kodmasin

2

En primer lugar, debe asignar a la url:

url(r'^blog/(?P<item_id>\d+)/$', 'blog.ajax.remove_item', name='blog-item'), 

entonces usted podría pasar URLs como variables a su módulo:

<script src="{{ STATIC_URL }}js/my-module.js"></script> 
<script> 
$(function(){ 
    MyModule.init('{% url blog-item item.id %}'); 
}); 
</script> 
// js/my-module.js 
var MyModule = { 
    init: function(url) { 
     console.log(url); 
    } 
}; 

Usted podría utilizar fichas en su url:

<script src="{{ STATIC_URL }}js/my-module.js"></script> 
<script> 
$(function(){ 
    MyModule.init("{% url blog-item item_id='0000' %}"); 
}); 
</script> 
// js/my-module.js 
var MyModule = { 
    init: function(url) { 
     var id = 1; 
     this._url = url; 
     console.log(this.url(id)); 
    }, 
    url: function(id) { 
     return this._url.replace('0000', id); 
    } 
}; 

Observe que su token debe coincidir con el tipo de expresión regular para resolverlo correctamente (no puedo usar {item_id} como token porque está definido con \d+).

Estaba un poco insatisfecho con esta solución y terminé escribiendo mi propia aplicación para manejar javascript con django: django.js. Con esta aplicación, que puedo hacer:

{% load js %} 
{% django_js %} 
{% js "js/my-module.js" %} 
// js/my-module.js 
var MyModule = { 
    init: function() { 
     var id = 1; 
     console.log(Django.url('blog-item', id)); 
    } 
}; 

$(function(){ 
    MyModule.init(); 
}); 
6

Hemos creado una pequeña aplicación llamada django-js-reverse para este propósito.

Por ejemplo, puede recuperar una llamada URL

urls.py:??

url (r '^/Betterliving/(P [- \ w] +)/(P \ d +)/$', 'get_house', name = 'betterliving_get_house'),

en javascript como:

URLs.betterliving_get_house ('casa', 12)

resultado:

/Betterliving/casa/12/

1

Puede eliminar los parámetros de la URL, y pasar las partes dinámicas como parámetros de consulta:

$('#add-choice-button').on('click', function() { 
    var thing_id = $(this).closest('.thing').attr('data-item-id'); 
    $.get('{% url 'addThing' %}?t='+thing_id, function (data) { 
     ... 
    }); 
    }); 
0

he encontrado esta aplicación fresco Django Django llamado JS inversa

https://github.com/ierror/django-js-reverse

Si tiene una URL como

url(r'^/betterliving/(?P<category_slug>[-\w]+)/(?P<entry_pk>\d+)/$', 'get_house', name='betterliving_get_house'), 

Entonces haces

Urls.betterliving_get_house('house', 12) 

El resultado es

/betterliving/house/12/