2009-11-25 14 views
22

Nel mio progetto ho molti metodi Ajax, con script esterni lato client (non voglio includere JavaScript nei template!) E cambiare gli URL è una specie di problema per me perché io è necessario modificare manualmente gli URL nelle mie chiamate Ajax.Django reverse() per JavaScript

C'è un modo per emulare il comportamento di {% url %} templatetag in JavaScript?

Ad esempio, stampare gli urlpattern a partire da ^ajax e successivamente negli script sostituire i modelli con i loro valori effettivi?

Questo è quello che mi viene in mente, e la mia domanda è - ci sono pratiche comuni per fare cose del genere? Forse alcune applicazioni riutilizzabili? Inoltre sarò felice di leggere tutti i consigli e i pensieri rilevanti che hai.

Update 1: sto parlando di URL calcolati, non quelli statici:

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

risposta

10

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

dutils è una piccola libreria di utilità che mira a fornire agli sviluppatori JavaScript/Django con alcune utilità che consentono lo sviluppo di RIA in cima ad una Django backend.

Attualmente supporta le seguenti caratteristiche:

  • metodo inversa per la generazione degli URL Django ...
+0

Controllate anche alcune delle forcelle. Dimitri-Gnidash crea gli URL con un comando di gestione. ljosa ha creato una vista che li costruisce al volo. – SystemParadox

+0

Sembra che questa soluzione richieda ancora l'hardcod del dizionario {url_name: pattern}. sarebbe bello automatizzare la generazione della lista trovata in dutils.conf.urls.example.js ??? – Fydo

+0

@Fydo usa per questo https://github.com/ierror/django-js-reverse –

4

Quello che di solito fare è mettere l'URL sia un elemento <input type="hidden" />, o l'attributo rel="".

Poi, quando si scrive il JS (utilizzando jQuery sotto) che faccio:

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

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

attributi non standard sono ben supportato da tutti i principali browser e gli elementi nascosti non devono essere in forma.

+0

Cosa faresti con gli URL calcolati? url (r '^ ajax/cancella/(? P immagine | audio)/(? P \ d +)/da/set/(? P \ d +)/$', 'blog.ajax.remove_item_from_set') , – dir01

+0

Li metti da qualche parte sulla pagina (nel modello django) - il javascript è un file separato che non è generato da django. –

14

Cosa c'è di sbagliato nel mettere JavaScript nei tuoi modelli?

Spesso si desidera chiamare una funzione di inizializzazione nel proprio modello HTML, quindi perché non passare un oggetto contenente gli URL che verranno utilizzati?

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

Se vi trovate a passare un sacco di variabili in questo modo, o che vogliono usare la logica nel vostro JavaScript che si fa nei vostri modelli HTML, allora perché non rendere il vostro script attraverso il motore di template di Django? Ricorda, i modelli di Django non sono solo per i documenti HTML, spesso aiuta a utilizzare i modelli per testo semplice, XML, JSON e sì anche JavaScript. Preoccupato per le prestazioni? Quindi archivia il risultato.

+0

Queste sono le iniziali del mio compito, quindi affrontalo) I file JS verrebbero consegnati tramite CDN. Quello che posso fare è mettere urlpatterns nella parte superiore della mia pagina (impostare le variabili js) e compilare url reali da espressioni regolari con dati reali – dir01

+3

Lo svantaggio di questo approccio è che non c'è modo di usare gli argomenti della vista. – intgr

+0

In base alla progettazione, mescolare i linguaggi è una cattiva idea. – azmeuk

16

provare a creare funzioni javascript helper (in modello Django) per la generazione di stringa URL. In forma semplice potrebbero apparire così:

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

Forse questo ha altre implicazioni ma penso che dovrebbe funzionare.

+0

Mi salvi la vita, grazie! Solo un'osservazione, suppongo che sia meglio usare id = 0 nel segnaposto perché non avrai mai un uguale a 0, non potremmo dire lo stesso per 112233, ma nell'altro si può cambiare tutto lo 0 della stringa, forse dovremmo un modello per cambiare nella giusta posizione. –

+0

Sono felice che ti piaccia la mia soluzione. Per quanto riguarda l'id è più importante che il valore che stai sostituendo non sia da qualche altra parte nella stringa url. Quindi in realtà non lo è 0 o 112233 fino a quando lo stesso valore non è altrove nella stringa url. – kodmasin

2

In primo luogo, si dovrebbe chiamare il vostro url:

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

allora si potrebbe passare URL come variabili al modulo:

<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); 
    } 
}; 

Si potrebbe utilizzare i gettoni nel vostro 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); 
    } 
}; 

Si noti che il token deve corrispondere al tipo di espressione regolare da risolvere correttamente (non è possibile utilizzare {item_id} come token perché è definito con \d+).

Ero un po 'insoddisfatto di questa soluzione e ho terminato scrivendo la mia applicazione per gestire javascript con django: django.js. Con questa applicazione, che posso fare:

{% 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

abbiamo creato una piccola applicazione chiamata django-js-reverse per questo scopo.

Per esempio è possibile recuperare un URL di nome

urls.py:??

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

in JavaScript come:

URL.betterliving_get_house ('casa', 12)

risultato:

/betterliving/casa/12/

1

È possibile rimuovere i parametri dall'URL, e passare i parti dinamiche come parametri di query:

$('#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

ho trovato questo app Django Django chiamato cool JS invertono

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

Se si dispone di un URL come

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

poi si fa

Urls.betterliving_get_house('house', 12) 

Il risultato è

/betterliving/house/12/