2010-07-01 2 views
22

Ho un'app django, un'app per i forum, con i suoi modelli. In quei modelli, ci sono URL che puntano a parti dell'app. Per esempio il modello thread_list ha collegamenti a ogni thread in questo modo:Come utilizzare gli URL dei nomi con django in un'app riutilizzabile

{% for thread in threads %} 
    <a href="{% url forum_thread thread %}">{{thread.title}}</a> 
{% endfor %} 

Il fatto è che non mi piace molto di chiamare i miei URL "forum_thread". Preferisco solo "thread" e uso la funzione namespace di django. "Forum_thread" può essere utilizzato da qualche altra parte nel progetto (collisione namespace) .Così che sarà simile a questa:

{% for thread in threads %} 
    <a href="{% url forum:thread thread %}">{{thread.title}}</a> 
{% endfor %} 

ma questo non si sente come il modo corretto per farlo. I documenti non sono chiari qui.

Voglio che questa app sia riutilizzabile e facile da configurare. Ma voglio anche usare i migliori standard. Non desidero che l'utente specifichi il proprio nome di spazio dei nomi e quindi le modifichi ogni singolo URL in ogni modello.

Come devo fare urls in questa app?

+0

Ho esattamente lo stesso dilemma! Urto! – frnhr

+0

Ti sei mai svegliato con qualcosa? Sto vivendo lo stesso problema e non sono sicuro di come dovrebbero essere fatte le cose. – Luke

risposta

14

Da quanto posso raccogliere dovresti poter usare {% url forum: thread thread%} come hai descritto. I namespace sembrano sempre essere definiti con due variabili, namespace e app_name.

Se poi eseguire le seguenti operazioni in urls.py:

url(r'^/forum/', include('forum.urls', namespace='forum', app_name='forum')), 
url(r'^/foo/', include('forum.urls', namespace='foo', app_name='forum')), 
url(r'^/bar/', include('forum.urls', namespace='bar', app_name='forum')), 

Nella mia comprensione, questo definisce 3 istanze della app 'forum', 'foo', 'bar', e il default (che ha namespace == nome_app.).

Quando si inverte il forum: thread, utilizza il contesto corrente per determinare quale utilizzare, se si utilizza lo spazio dei nomi 'foo' lo userà, altrimenti ricadrà sul valore predefinito.

Se qualcuno è in grado di chiarire come Django decide quale sia lo spazio dei nomi/app "attuale" sarebbe molto utile. Attualmente lo classifico come "magia nera".

Sarebbe utile anche qualche chiarimento sulla differenza effettiva tra lo spazio dei nomi e il nome app: è possibile che sia completamente invertito. I documenti attuali sono altamente ambigui.

Nota: questo funziona per le richieste iniziali, ma al momento non riesco a farlo funzionare per le richieste AJAX, quelle utilizzano sempre l'istanza predefinita per qualche motivo.

+2

Questo è ora specificato nei documenti e sembra che tu abbia corretto: https: //docs.djangoproject.it/it/dev/topics/http/urls/# reversing-namespaced-urls Penso che non sia necessario specificare 'app_name = 'forum'' a meno che tu non voglia usare qualcosa di diverso dal nome del modulo. Suppongo che se non lavori per richieste AJAX è forse perché stai rendendo la risposta in modo diverso (forse non utilizzi un modello o non usi RequestContext) e quindi l'applicazione corrente deve essere specificata manualmente quando si invertono gli URL. – Anentropic

+1

Il problema è che questo URL può essere incluso solo negli URL radice. Cioè c'è un _app_ con un'app _site_ inclusa negli URL root _app/urls.py_: 'url (r '^/site /', include ('site.urls', namespace = 'site', app_name = 'site' ', _site_ app include il forum: ' url (r '^/forum /', include ('forum.urls', namespace = 'forum', app_name = 'forum')) ' Rompe il forum come i suoi url non può essere annullato come 'forum: *' ma 'sito: forum' * ' –

1

Questo potrebbe essere un semplice errore di sintassi. Stavo seguendo il Django Tutorial, e ho cambiato mysite/urls.py in modo improprio. La sintassi originale:

url(r'^polls/', include('polls.urls')), 

il cambiamento desiderato:

url(r'^polls/', include('polls.urls', namespace="polls")), 

Quello che ho fatto:

url(r'^polls/', include('polls.urls'), namespace="polls"), 

Correzione la sintassi ha risolto il problema.