2012-02-16 7 views
17

Diciamo che ho un progetto Django con tre app: foo, bar e colla. Sto cercando di seguire le convenzioni delle app riutilizzabili, quindi foo e bar non dipendono (e non ne sanno nulla) l'un l'altro o sulla colla. Colla contiene codice per integrare le altre due app nel sito.Django: Come faccio a sovrascrivere gli URL forniti dall'app nel mio progetto urlconf?

Foo fornisce un tag modello che desidero includere in una delle pagine fornite dalla barra. La vista per la pagina della barra può essere passata a un modello alternativo. Creo un modello in colla che estende il modello della barra e include il tag modello di foo. Per passare il mio nuovo modello alla visualizzazione della barra, ho bisogno di modificare la voce urlconf che punta ad essa.

Il mio progetto urlconf simile a questa:

urlpatterns = patterns('', 
    (r'^$', include('glue.urls')), 
    (r'^foo/', include('foo.urls')), 
    (r'^bar/', include('bar.urls')), 
) 

Qual è il modo più elegante per passare il modello alternativo (o qualsiasi altra vista argomenti arbitrari, se è per questo) per la visualizzazione in bar? Non voglio modificare direttamente urlconf della barra, in quanto ciò renderebbe dipendente dalla colla.

L'unico altro metodo che viene in mente è quello di rimuovere include('bar.urls'), copiare i modelli di URL in urlconf di barra nel urlconf progetto e modificare il modello che mi interessa. Tale impostazione viola il principio DRY però. C'è qualche altra soluzione che mi manca?

risposta

23

Apparentemente URL duplicati sono ammessi nel urlconf, e la prima partita di cui avranno la priorità:

urlpatterns = patterns('', 
    (r'^$', include('glue.urls')), 
    (r'^foo/', include('foo.urls')), 

    # This will override the same URL in bar's urlconf: 
    (r'^bar/stuff/$', 'glue.views.new_bar_stuff', {'arg': 'yarrgh'}, 'bar_stuff'), 

    (r'^bar/', include('bar.urls')), 
) 
2

Non è chiaro che cosa state chiedendo, ma se ho capito bene, la tua domanda è:

Qual è il modo più elegante per passare il modello alternativo alla vista in bar?

Questo non ha nulla a che fare con l'url conf, che associa solo gli URL ai metodi.

modelli in Django vengono ricercati dalle posizioni in TEMPLATE_DIRS nel vostro settings.py, e, soprattutto, Django si fermeranno alla ricerca una volta che trova un modello.

Se il tuo TEMPLATE_DIRS è vuoto (come predefinito), django cercherà i modelli in una directory templates all'interno di qualsiasi app registrata (app elencate in INSTALLED_APPS).

Quindi, per passare un modello alternativo a qualsiasi applicazione, è sufficiente creare un file con lo stesso nome (e struttura di directory) in una directory elencata in TEMPLATE_DIRS. Django cercherà prima questo e si fermerà quando troverà una corrispondenza.

Questo è lo stesso modo in cui si ignorano i modelli di amministrazione predefiniti.

Per il caso specifico, si supponga di voler passare una versione alternativa di index.html all'app bar.

Creare una directory override_templates da qualche parte nel percorso del progetto.

All'interno di tale cartella creare la directory bar/templates/ e aggiungere il proprio numero di telefono personalizzato index.html a questa directory, in modo da avere override_templates/bar/templates/index.html.

Aggiungere il percorso completo a override_templates a TEMPLATE_DIRS in settings.py.

Ora django cercherà prima la directory personalizzata per qualsiasi modello richiesto e caricherà il tuo index.html alternativo.

+2

Cercherò in questo approccio, ma non è proprio quello che sto cercando. Cosa succede se volevo passare in qualche altro argomento alla vista? La vista viene chiamata in urlconf, quindi sembra il posto logico per passare l'argomento. –

+0

Vuoi passare argomenti arbitrari alla vista? Chiarire la tua domanda per favore –

+1

Sì, simile agli argomenti che si sarebbero passati ad una vista generica da urlconf. –