2009-11-27 14 views
37

Sto iterando attraverso i campi di un modulo e per determinati campi voglio un layout leggermente diverso, che richiede HTML alterato.Ottieni il tipo di widget di forma Django dal modello

Per fare ciò con precisione, ho solo bisogno di conoscere il tipo di widget. Il nome della classe o qualcosa di simile. In Python standard, questo è facile! field.field.widget.__class__.__name__

Purtroppo, non è consentito l'accesso alle variabili di sottolineatura nei modelli. Ottimo!

È possibile prova field.field.widget.input_type ma questo funziona solo per il testo/password <input ../> tipi. Ho bisogno di più risoluzione per quello.

Per me, per quanto difficile possa sembrare, ha più senso farlo a livello di modello. Ho esternalizzato il bit di codice che gestisce l'HTML per i campi in un modello separato che viene incluso nel ciclo di campo. Ciò significa che è coerente tra ModelForm s e lo standard Form s (qualcosa che non sarebbe vero se avessi scritto una classe Form intermediario).

Se riesci a vedere un approccio universale che non mi richiede di modificare i moduli di 20 cifre, fammelo sapere anche io!

+0

Rilevante o caratteristica richiesta: https://code.djangoproject.com/ticket/13009 – Flimm

risposta

4

Come di Django 1.11, si può semplicemente utilizzare widget.input_type. Esempio: segnalazione di bug

{% for field in form.visible_fields %} 
    <input type="{{ field.field.widget.input_type }}" 
      id="{{ field.id_for_label }}" 
      name="{{ field.html_name }}" 
      placeholder="{{ field.label }}" 
      maxlength="{{ field.field.max_length }}" /> 
{% endfor %} 
40

Fare un tag modello potrebbe funzionare? Qualcosa come field.field.widget|widget_type

Modifica da Oli: buon punto! Ho appena scritto un filtro:

from django import template 
register = template.Library() 

@register.filter('klass') 
def klass(ob): 
    return ob.__class__.__name__ 

E ora {{ object|klass }} visualizzato correttamente. Ora devo solo capire come usarlo all'interno dell'istruzione if di un modello.

Modifica da Oli # 2: Avevo bisogno di utilizzare il risultato di questo in un modello statet in-template, così ho solo spostato tutta quella logica nel templatetag. Magia. Grazie per avermi spinto nella giusta direzione.

+0

Benvenuti a SO btw. – Oli

+1

Grazie per questa soluzione. Per quanto riguarda Modifica # 2 - con i tag 'if avanzati 'in Django 1.2, puoi fare questi confronti del tipo di widget direttamente nel modello. Ho pubblicato un esempio come risposta separata. – zlovelady

+1

Un altro filtro bello aggiungere (se non Python persone saranno gestendo i modelli) è qualcosa di simile, per i vostri casi più utilizzati: 'def is_checkboxes (form_field_obj): ritorno (form_field_obj .__ classe __.__ name__ == "CheckboxSelectMultiple ")' ... allora si può fare '{% se il campo | is_checkboxes%}' e la gente non impazzire (... non torna) – hangtwenty

33

In seguito alla risposta accettata - il potenziato if tag in Django 1.2 consente di utilizzare i filtri nei confronti if tag. Così si potrebbe ora fare il vostro html custom/logica nel modello in questo modo:

<ul> 
{% for field in form.fields %} 
    <li> 
    {% if field.field.widget|klass == "Textarea" %} 
    <!-- do something special for Textarea --> 
    <h2>Text Areas are Special </h2> 
    {% else %}  
     {{ field.errors }} 
     {{ field.label_tag }} 
     {{ field }} 
    {% endif %} 

    </li> 
{% endfor %} 
</ul> 
+3

+1 per il follow-up – Oli

+0

Qual è lo scopo di * * field.field.widget, al contrario di usando solo * * field.widget? – Wipqozn

+0

@Wipqozn nella mia esperienza 'field.widget' spesso non produce nulla - non ne sono sicuro, ma forse è impostato solo se lo si imposta manualmente. 'field.field.widget' funziona. – hangtwenty

16

In seguito alla risposta da Oli e Rinti: ho usato questo e penso che sia un po 'più semplice: il codice

modello : codice {{ field|fieldtype }}

filtro:

from django import template 
register = template.Library() 

@register.filter('fieldtype') 
def fieldtype(field): 
    return field.field.widget.__class__.__name__ 
Problemi correlati