Sto iterando attraverso i campi di un modulo e per determinati campi voglio un layout leggermente diverso, che richiede HTML alterato.
Per farlo con precisione, ho solo bisogno di conoscere il tipo di widget. Il nome della class o qualcosa di simile. In Python standard, questo è facile! field.field.widget.__class__.__name__
Sfortunatamente, non ti è consentito accedere alle variabili di sottolineatura nei modelli. Grande!
Puoi testare field.field.widget.input_type
ma questo funziona solo per i tipi text / password . Ho bisogno di più risoluzione per quello.
Per me, per quanto difficile possa sembrare, ha più senso farlo a livello di template. 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
e Form
standard (qualcosa che non sarebbe vero se avessi scritto una class Form intermedia).
Se riesci a vedere un approccio universale che non mi richiede di modificare i moduli di 20 cifre, fammelo sapere!
A partire da Django 1.11, puoi semplicemente usare widget.input_type
. Esempio:
{% for field in form.visible_fields %} {% endfor %}
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 }}
correttamente. Ora devo solo capire come usarlo all’interno dell’istruzione if
un template.
Modifica da Oli # 2: Avevo bisogno di usare il risultato di questo in un template statetario, quindi ho solo spostato tutta la logica nel templatetag. Magia. Grazie per avermi spinto nella giusta direzione.
In seguito alla risposta accettata – il if tag
potenziato if tag
in Django 1.2 consente di utilizzare i filtri in if tag
confronto di if tag
. Quindi ora puoi fare la tua html / logica personalizzata nel modello in questo modo:
{% for field in form.fields %} - {% if field.field.widget|klass == "Textarea" %}
Text Areas are Special
{% else %} {{ field.errors }} {{ field.label_tag }} {{ field }} {% endif %} {% endfor %}
Seguendo la risposta di Oli e rinti: ho usato questo e penso che sia un po ‘più semplice:
codice modello: {{ field|fieldtype }}
codice filtro:
from django import template register = template.Library() @register.filter('fieldtype') def fieldtype(field): return field.field.widget.__class__.__name__
Forse vale la pena di ricordare ai lettori contemporanei che django-widget-tweaks
fornisce filtri modello field_type
e widget_type
per questo scopo, restituendo i rispettivi nomi di class in widget_type
minuscole. Nell’esempio che segue mostro anche l’output della proprietà input_type
sul widget campo (da Django 1.11), che può anche essere utile.
forms.py
:
class ContactForm(forms.Form): name = forms.CharField( max_length=150, required=True, label='Your name' )
template.html
:
{% load widget_tweaks %} {% for field in form.visible_fields %} {{ field.label }} {{ field.field.widget.input_type }} {{ field|field_type }} {{ field|widget_type }}) {% endfor %}
Risultato:
Your name text charfield textinput
Tra queste varie opzioni dovresti essere in grado di trovare la proprietà giusta da utilizzare per quasi ogni caso d’uso. Se è necessario acquisire l’output di uno di questi filtri da utilizzare nelle istruzioni if
, è ansible utilizzare il tag with
modello.