2009-12-13 9 views

Antwort

2

hatte ich dieses Problem und ich habe ein neues Widget:

from django.forms.widgets import Select 
from django.utils.safestring import mark_safe 
class PrepolutatedSelect(Select): 
    def render(self, name, value, attrs=None, choices=()): 
     if value is None: value = '' 
     if value == '': 
      value = int(name.split('-')[1])+1 
     final_attrs = self.build_attrs(attrs, name=name) 
     output = [u'<select%s>' % flatatt(final_attrs)] 
     options = self.render_options(choices, [value]) 
     if options: 
      output.append(options) 
     output.append('</select>') 
     return mark_safe(u'\n'.join(output)) 

Vielleicht wird dies auch für Sie arbeiten.

+0

Ich habe ein ähnliches Problem mit dem OP. Ich versuche, ein Formset mit mehreren Formen zu erstellen, wobei jedes Formular seinen eigenen eindeutigen Satz von Optionen für ein Auswahlelement (d. H. "Auswahlmöglichkeiten") aufweist. Ich kann mir nicht vorstellen, wie diese Lösung helfen würde. Fehle ich etwas? – ACPrice

10

Sie müssen die in this post beschriebene Technik verwenden, um Parameter übergeben zu können. Kredit an diesen Autor für einen ausgezeichneten Beitrag. Sie erreichen dies in mehreren Teilen:

A bilden bewusst, dass es zusätzliche Parameter

Beispiel aus der verknüpften Frage abholen wird:

def __init__(self, *args, **kwargs): 
    someeobject = kwargs.pop('someobject') 
    super(ServiceForm, self).__init__(*args, **kwargs) 
    self.fields["somefield"].queryset = ServiceOption.objects.filter(
                  somem2mrel=someobject) 

Oder Sie können die letztere Code mit

ersetzen
self.fields["somefield"].initial = someobject 

Direkt, und es funktioniert.

A curried Form Initialisierung Setup:

formset = formset_factory(Someform, extra=3) 
formset.form = staticmethod(curry(someform, somem2mrel=someobject)) 

Dass Sie bekommt auf Parameter benutzerdefinierte Formular übergeben. Nun, was Sie brauchen, ist:

Ein Generator zu erwerben Ihre unterschiedlichen Anfangsparameter

Ich benutze dieses:

def ItemGenerator(Item): 
    i = 0 
    while i < len(Item): 
     yield Item[i] 
     i += 1 

Nun, ich kann dies tun:

iterdefs = ItemGenerator(ListofItems) # pass the different parameters 
             # as an object here 
formset.form = staticmethod(curry(someform, somem2mrel=iterdefs.next())) 

Hey presto. Jede Bewertung der form-Methode wird in Teilen ausgewertet, die einen iterierten Parameter übergeben. Wir können über das, was wir mögen, iterieren, also verwende ich diese Tatsache, um über eine Menge von Objekten zu iterieren und den Wert von jedem als einen anderen Anfangsparameter zu übergeben.

+0

hey! Ich denke, dass Ihre Antwort das Problem lösen kann, das ich in dieser Frage anspreche http://stackoverflow.com/questions/6123278/same-form-different-variables-how-to-implement. Aber ich verstehe nicht wirklich, was passiert – pavid

+1

Ich habe versucht, mit diesem Ansatz, aber kann nicht den Iterator bei jedem Aufruf iterieren. Mein Code: 'DecorationFileFormSet.form = staticmethod (curry (DecorationFileForm, filetype = counter.next()))' erstellt Formulare, in denen das Dateityp-Attribut jedes Mal 1 ist. counter ist eine Instanz von 'itertools.count (1)' –

+0

Hat jemand schon eine Lösung? Der Generator funktioniert nicht (iteriert überhaupt nicht) auch für mich. – wgx731

2

Aufbauend auf Antony Vennards Antwort bin ich nicht sicher, welche Version von Python/Django er benutzt, aber ich konnte den Generator auch nicht in der Curry-Methode arbeiten lassen. Ich bin derzeit auf Python2.7.3 und Django1.5.1. Anstatt einen benutzerdefinierten Generator zu verwenden, habe ich am Ende den eingebauten iter() für eine Liste von Dingen verwendet, um einen Iterator zu erstellen und den Iterator selbst in der curry-Methode zu übergeben und next() darüber in Form__init__() aufzurufen.Hier ist meine Lösung:

# Build the Formset: 
my_iterator = iter(my_list_of_things) # Each list item will correspond to a form. 
Formset = formset_factory(MyForm, extra=len(my_list_of_things)) 
Formset.form = staticmethod(curry(MyForm, item_iterator=my_iterator)) 

Und in der Form:

# forms.py 
class MyForm(forms.Form): 
    def __init__(self, *args, **kwargs): 
     # Calling next() on the iterator/generator here: 
     list_item = kwargs.pop('item_iterator').next() 

     # Now you can assign whatever you passed in to an attribute 
     # on one of the form elements. 
     self.fields['my_field'].initial = list_item 

Einige wichtige Dinge, die ich gefunden waren, dass müssen Sie entweder ein ‚Extra‘ Wert in der formset_factory angeben oder die initial kwarg verwenden auf das Formset zum Angeben einer Liste, die der Liste entspricht, die Sie an den Iterator übergeben (im obigen Beispiel übergebe ich die len() der Liste my_list_of_things an 'extra' kwarg an formset_factory). Dies ist erforderlich, um tatsächlich eine Anzahl von Formularen im Formset zu erstellen.

33

Wenn Sie den gleichen Fehler gemacht haben wie ich, haben Sie die Dokumentation leicht verwechselt.

Als ich dieses Beispiel zum ersten Mal sah ...

formset = ArticleFormSet(initial=[ 
{'title': 'Django is now open source', 
    'pub_date': datetime.date.today(),} 
]) 

ging ich davon aus, dass jede Form den gleichen Satz von Ausgangsdaten auf einem Wörterbuch basieren gegeben ist.

Wenn Sie jedoch genau hinschauen, sehen Sie, dass dem Formset tatsächlich eine Liste von Wörterbüchern übergeben wird.

Um für jedes Formular in einem Formularsatz unterschiedliche Anfangswerte festzulegen, müssen Sie lediglich eine Liste von Wörterbüchern mit den verschiedenen Daten übergeben.

Formset = formset_factory(SomeForm, extra=len(some_objects) 
some_formset = FormSet(initial=[{'id': 'x.id'} for x in some_objects]) 
+2

Dies scheint der einfachste Weg zu sein, um dies zu tun, und der Standard Django Weg, es zu tun, und zeigt genau das Missverständnis, das das OP hatte. Sollte die beste Antwort sein. – ACPrice

+1

Beachten Sie, dass dies "ArticleFormSet" zu einem [ungebundenen Formular] macht (https://docs.djangoproject.com/en/1.10/topics/forms/#bound-and-unbound-form-instances), da die ursprünglichen Werte überschrieben werden die Werte, die von dem Article-Abfrage-Set zurückgegeben werden. –

Verwandte Themen