with - templates in django




Django: passaggio argomento al modello padre (4)

Ho modelli di questo stile

project
- main_templates (including nav bar)
-- app1
--- app1_base_template
--- app1_templates
-- app2
--- app2_base_template
--- app2_templates

Quindi, durante il rendering, app2_templates estende app2_base_template che estende main_template.

Quello che devo fare è avere l'oggetto di navigazione corrispondente in grassetto quando viene eseguito il rendering del modello di app2 (per mostrare all'utente dove si trova).

Il più semplice sarebbe se potessi passare una variabile nella parte {% block xxx%}. È possibile ?

Quali altri modi generici ci sono?


Hai provato il tag del template {% with%}?

{% block content %}
  {% with 'myvar' as expectedVarName %}
  {{block.super}}
  {% endwith %}
{% endblock content %}

Ho preso l'approccio "low tech" di Jarret Hardie in un contesto simile, errato (sì, è un gioco di parole ... che non ha senso per te se non ti dico che non stavo facendo navs ma impostando il colore del bordo dei pulsanti per mostrare quale era stato premuto).

Ma la mia versione è un po 'più compatta, penso. Invece di definire una sola variabile attiva della variabile di contesto nella vista, restituisco un dizionario, ma sempre con una sola coppia chiave-valore: ad esempio activebar = {'foo': 'active'}.

Quindi nel modello scrivo semplicemente class = "{{activebar.foo}}" nell'ancoraggio foo, e corrispondentemente negli altri ancore. Se solo activebar.foo è definito per avere il valore "active" allora activebar.bar nella barra di ancoraggio non farà nulla. Forse "fallire silenziosamente" è il giusto discorso di Django. E Bob è tuo zio.

EDIT: Oops ... un paio di giorni sono passati, e mentre quello che avevo scritto sopra ha funzionato per me un problema è apparso quando ho messo nella barra di navigazione un ancoraggio con una nuova finestra come destinazione. Sembrava essere la causa di uno strano problema: dopo aver fatto clic sulla nuova finestra (scheda in Firefox) e poi tornare a quello da cui era stata lanciata la nuova finestra, le porzioni del display sotto la barra di navigazione diventavano vuote ogni volta che spostavo rapidamente la Cursore sopra gli oggetti sulla barra di navigazione --- senza fare clic su nulla. Ho dovuto forzare il ridisegno dello schermo spostando la barra di scorrimento (non una pagina di ricaricamento, anche se anche questo ha funzionato perché comporta un ridisegno dello schermo).

Sono troppo truccato per capire perché potrebbe accadere. Ed è possibile che io abbia fatto qualcos'altro che ha causato il problema che in qualche modo è andato via. Ma ... ho trovato un approccio più semplice che funziona perfettamente per me. Le mie circostanze sono che ogni modello figlio che viene lanciato da una vista dovrebbe causare la visualizzazione di un elemento della barra di navigazione come "attivo". In effetti, quell'elemento della barra di navigazione è quello che ha lanciato la vista che ha lanciato il modello figlio --- il solito affare.

La mia soluzione --- prendiamo come esempio un elemento della barra di navigazione "login" --- è per mettere questo nel modello figlio che contiene il modulo di login.

{% block login %}active{% endblock %}

L'ho messo sotto il cartiglio ma non credo che il posizionamento abbia importanza. Quindi nel modello principale che contiene la definizione della barra di navigazione, per il tag li che circonda l'ancora per l'elemento della barra di navigazione di accesso che ho messo ... beh, ecco il codice:

<li class="{% block login %}{% endblock %}"><a href="/mysite/login">Login</a></li>

Pertanto, quando il modello secondario viene renderizzato, il genitore mostrerà l'elemento della barra di navigazione come attivo e Bob è ancora tuo zio.

L'approccio del dizionario che ho descritto sopra era per mostrare quale di una linea di pulsanti era stata premuta, quando erano tutti sullo stesso modello figlio. Funziona ancora per me e visto che è coinvolto un solo modello figlio, non vedo come il mio nuovo metodo per i navbar possa funzionare in quella circostanza. Si noti che con il nuovo metodo per le viste del navbar non sono nemmeno coinvolte. Più semplice!


Le variabili del modello principale vengono automaticamente incluse nell'ambito del figlio. Il tuo titolo dice che vuoi passare una variabile al genitore, che non ha senso, dato che non puoi definire variabili nei template. Se ti serve una variabile sia nel genitore che nel bambino, devi solo dichiararla nella vista.


Non esiste un modo diretto per passare una variabile lungo l'albero di ereditarietà del modello come descritto. Il modo in cui le persone implementano le barre di navigazione che evidenziano la pagina corrente viene spesso ottimizzato sulla natura del sito stesso. Detto questo, ho visto due approcci comuni:

L'approccio low-tech

Passa una variabile nel contesto del modello che indica quale scheda è attiva:

# in views.py
def my_view(request):
    return render_to_response('app2_template.html', {"active_tab": "bar"},

<!-- Parent template -->
<div id="navigation">
    <a href="/foo" {% ifequal active_tab "foo" %}class="active"{% endifequal %}>Foo</a>
    <a href="/bar" {% ifequal active_tab "bar" %}class="active"{% endifequal %}>Bar</a>
</div>

L'approccio high-tech

Implementa un tag modello personalizzato per il rendering della barra di navigazione. Chiedi al tag di prendere una variabile che indica quale sezione è attiva:

<!-- Parent template -->

<div id="navigation">{% block mainnav %}{% endblock %}</div>

<!-- any child template -->
{% load my_custom_nav_tag %}
{% block mainnav %}{% my_custom_nav_tag "tab_that_is_active" %}{% endblock %}

Puoi praticamente impazzire da li '. Potresti scoprire che qualcuno ha già implementato qualcosa che funzionerà per te su djangosnippets.org.





django-templates