2009-01-04 8 views
18

Ist es möglich, eine variable Anzahl von Feldern mit Django-Formularen zu haben?Variable Anzahl von Eingängen mit Django-Formen möglich?

Die spezifische Anwendung ist dies:

Ein Benutzer kann so viele Bilder hochladen, wie sie auf dem Bild-Upload-Formular möchten. Sobald die Bilder hochgeladen sind, werden sie auf eine Seite gebracht, wo sie den Bildern einen Namen und eine Beschreibung geben können. Die Anzahl der Bilder hängt davon ab, wie viele Nutzer der Upload gewählt hat.

So Wie bekomme ich Django, um ein Formular mit einer variablen Anzahl von Eingabefeldern (die als Argument übergeben werden könnte, wenn nötig) zu generieren?

bearbeiten: ein paar Dinge haben sich geändert, seit die article mentioned in jeff bauer's answer geschrieben wurde.

nämlich diese Codezeile, die nicht zu funktionieren scheint:

# BAD CODE DO NOT USE!!! 
return type('ContactForm', [forms.BaseForm], { 'base_fields': fields }) 

Also hier ist, was ich mit ...

Die Antwort habe ich kam:


from tagging.forms import TagField 
from django import forms 

def make_tagPhotos_form(photoIdList): 
    "Expects a LIST of photo objects (ie. photo_sharing.models.photo)" 

    fields = {} 

    for id in photoIdList: 
     id = str(id) 

     fields[id+'_name'] = forms.CharField() 
     fields[id+'_tags'] = TagField() 
     fields[id+'_description'] = forms.CharField(widget=forms.Textarea) 

    return type('tagPhotos', (forms.BaseForm,), { 'base_fields': fields }) 

Hinweis Tagging ist nicht Teil von Django, aber es ist kostenlos und sehr nützlich. Check it out: django-tagging

Antwort

15

Ja, es ist möglich, dynamisch Formulare in Django zu erstellen. Sie können dynamische Felder sogar mit normalen Feldern kombinieren und abgleichen.

class EligibilityForm(forms.Form): 
    def __init__(self, *args, **kwargs): 
     super(EligibilityForm, self).__init__(*args, **kwargs) 
     # dynamic fields here ... 
     self.fields['plan_id'] = CharField() 
    # normal fields here ... 
    date_requested = DateField() 

Für eine bessere Ausarbeitung dieser Technik finden James Bennett Artikel: So haben Sie eine dynamische Form wollen?

http://www.b-list.org/weblog/2008/nov/09/dynamic-forms/

7

Wenn Sie

python manage.py shell 

und Art ausführen:

from app.forms import PictureForm 
p = PictureForm() 
p.fields 
type(p.fields) 

Sie werden sehen, dass p.fields ist ein SortedDict. Sie müssen nur ein neues Feld einfügen. So etwas wie

p.fields.insert(len(p.fields)-2, 'fieldname', Field()) 

In diesem Fall würde es vor dem letzten Feld ein neues Feld einfügen. Sie sollten sich jetzt an Ihren Code anpassen.

Andere Alternative ist eine For/While-Schleife in Ihrer Vorlage zu machen und das Formular in HTML zu tun, aber Django Formen Rock aus irgendeinem Grund, oder?

+0

gab man fast die akzeptierte Antwort, Jeffs war nur ein wenig klarer (der Link sehr geholfen) – Jiaaro

7

Verwenden entweder mehr Formen (django.forms.Form nicht der Tag)

class Foo(forms.Form): 
    field = forms.Charfield() 

forms = [Foo(prefix=i) for i in xrange(x)] 

oder mehr Felder zum Formular unter Verwendung von dynamisch self.fields hinzuzufügen.

class Bar(forms.Form): 
    def __init__(self, fields, *args, **kwargs): 
     super(Bar, self).__init__(*args, **kwargs) 
     for i in xrange(fields): 
      self.fields['my_field_%i' % i] = forms.Charfield()