2012-04-28 3 views
6

Dire che ho un modulo con 20 campi e voglio mettere 10 di questi campi (gruppo1) in un particolare ambiente div e gli altri 10 campi (gruppo2) in un diverso ambiente div. Qualcosa di simile:Raggruppamento dei campi modulo Django

<div class="class1"> 
{% for field in form.group1 %} 
      {{ field.label}}: {{ field }} 
{% endfor %} 
</div> 

<div class="class2"> 
{% for field in form.group2 %} 
      {{ field.label}}: {{ field }} 
{% endfor %} 
</div> 

Tutte le idee come avrei potuto ottenere questo risultato l'iterazione sui campi? Più in generale, mi piacerebbe poterlo fare con molti diversi ambienti div e serie di campi modulo.

risposta

13

Qualsiasi metodo logico per raggruppare i campi funzionerebbe ... dite che avete un metodo sul modulo che restituisce i campi modulo che raggruppate in modo esplicito?

Per salvare la digitazione, forse un determinato schema di denominazione del prefisso di campo?

class MyForm(forms.Form): 
    group1_field = forms.CharField() 
    group1_field = forms.CharField() 
    group2_field = forms.CharField() 
    group2_field = forms.CharField() 

    def group1(self): 
     return [self[name] for name in filter(lambda x: x.startswith('group1_'), self.fields.values()] 

Forse impostare un attributo sul campo che è possibile filtrare per?

class MyForm(forms.Form): 
    field = forms.CharField() 
    field.group = 1 

    field2 = forms.CharField() 
    field2.group = 2 

    def group1(self): 
     return filter(lambda x: x.group == 1, self.fields.values()) 

    def group2(self): 
     return filter(lambda x: x.group == 2, self.fields.values()) 

È possibile utilizzare il tag di gruppo se si impostano questi attributi.

{% regroup form.fields by group as field_group %} 
{% for group in field_group %} 
<div class="group_{{ group.grouper }}"> 
    {% for field in group.list %} 
    {{ field }} 
    {% endfor %} 
</div> 
{% endfor %} 
+0

Mi piace l'utilizzo del tag di registro --- Non sapevo che esistesse. Grazie! –

+0

Nota: la prima soluzione non funziona per eseguire il loop sui campi del modello --- utilizzare la parola chiave 'yield' per creare un generatore per ottenere i campi previsti (vedere il post seguente) ed emulare l'iterazione di campo tipica di django –

+0

@ C.Reed, hai ragione, ho dimenticato di restituire BoundFields. Aggiornato. Grazie per aver notato! –

4

Ecco una domanda SO pertinente: Django and Fieldsets on Modelform, anche se questo sembra un po 'eccessivo per quello che sto cercando di realizzare. Inoltre, ecco un possibile trucco, anche se sono curioso di sapere come gli esperti di Django risolvono questo problema.

(0) Definire un oggetto pitone fieldset che è iterabile in modo da poter scorrere su di esso in un modello django:

from django.forms.forms import BoundField 

class FieldSet(object): 
    def __init__(self,form,fields,legend='',cls=None): 
     self.form = form 
     self.legend = legend 
     self.fields = fields 
     self.cls = cls 

    def __iter__(self): 
     for name in self.fields: 
      field = self.form.fields[name] 
      yield BoundField(self.form, field, name) 

(1) Nell'uso visualizzazione:

fieldsets = (FieldSet(form_object, ('field_name1','field_name2'), 
         legend='Div env 1', 
         cls="class1"), 
      FieldSet(form_object, ('field_name3','field_name4'), 
         legend="Div env 2", 
         cls="class2")) 

return render_to_response('my_form.html', 
          {'form': form_object,'fieldsets':fieldsets}, 
          context_instance=RequestContext(request)) 

(2) Ora, nel modello fare:

{% for set in fieldsets %} 
    <fieldset{% if set.cls %} class="{{ set.cls }}"{% endif %}> 
     <legend>{{ set.legend }}</legend> 
     {% for field in set %} 
      {{ field.label}} : {{ field }} 
     {% endfor %} 
    </fieldset> 
{% endfor %} 

si noti che è possibile sostituire il fieldset tag wi un tag div per rispondere alla mia domanda specifica.

+++ Gran parte di questa risposta è stata estratta da this blog post by Michael Kowalchik. +++

+0

'rendimento self.form [nome]' è sufficiente. (Ho avuto problemi con l'importazione di BoundField ma con quella linea non è nemmeno necessario.) – Risadinha