2009-12-13 64 views

回答

2

我有這個問題,我做了一個新的小工具:

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)) 

也許這會爲你工作了。

+0

我有一個與OP類似的問題。我試圖創建一個具有多種形式的表單,每個表單都有自己獨特的選擇元素集(即「選擇」)。我不太明白這個解決方案會有什麼幫助。我錯過了什麼嗎? – ACPrice 2015-07-08 06:44:49

10

您需要使用this post中描述的技術,以便能夠傳遞參數。發信給該作者以獲得出色的帖子。您在幾部分實現這一目標:

一種形式知道它會從關聯的問題

例拿起額外的參數:

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

或者你可以替換

後者碼
self.fields["somefield"].initial = someobject 

直接,它的工作原理。

一個令行禁止形式初始化設置

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

,讓你來傳遞自定義表單參數。現在,你需要的是:

的發生器獲得的不同的初始參數

我使用這個:

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

現在,我可以這樣做:

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

嘿presto。對迭代參數中傳遞的零件評估form方法的每個評估。我們可以迭代我們喜歡的東西,所以我使用這個事實來遍歷一組對象,並將每個對象的值作爲不同的初始參數傳遞。

+0

嘿!我認爲你的答案可能會解決我在這個問題中解決的問題http://stackoverflow.com/questions/6123278/same-form-different-variables-how-to-implement。但我其實不太明白髮生了什麼 – pavid 2011-05-25 15:46:32

+1

我嘗試過使用這種方法,但無法讓迭代器對每次調用進行迭代。我的代碼:'DecorationFileFormSet.form = staticmethod(Curry(DecorationFileForm,filetype = counter.next()))'創建每次filetype屬性爲1的表單。計數器是'itertools.count(1)'的一個實例' – 2012-04-18 15:50:21

+0

任何人都已經得到解決方案?發生器對我來說也不起作用(根本不反覆)。 – wgx731 2013-07-11 04:27:02

2

建立在安東尼維納德的答案,我不知道他使用的是什麼版本的python/django,但我無法讓生成器在咖喱方法中工作。我目前在python2.7.3和django1.5.1。我沒有使用定製的Generator,而是使用內置的iter()來創建迭代器,並將迭代器本身傳遞給curry方法,並在Form__init__()上調用next()。這裏是我的解決方案:

# 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)) 

而且形式:

# 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 

我發現了一些關鍵的事情是,你需要可以指定在formset_factory的「額外」值或使用initial kwarg formset指定一個列表,該列表對應於傳遞給迭代器的列表(在上例中,我將my_list_of_things列表的len()傳遞給'extra'kwarg以formset_factory)。這對於在formset中實際創建多個表單是必需的。

33

如果您和我犯了同樣的錯誤,您會錯誤地將文檔弄錯。

當我第一次看到這個例子...

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

我假定每個形式給出相同的一組基於字典的初始數據。

但是,如果仔細觀察,您會發現formset實際上正在傳遞一個字典列表。

爲了爲formset中的每個表單設置不同的初始值,您只需傳遞一個包含不同數據的字典列表。

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

這似乎是做到這一點的最簡單的方法,也是默認的Django方法,並指出了OP所具有的錯誤觀念。應該是最好的答案。 – ACPrice 2015-07-07 01:17:24

+1

請注意,這會使'ArticleFormSet'成爲[unbound form](https://docs.djangoproject.com/zh/1.10/topics/forms/#bound-and-unbound-form-instances),因爲初始值將被覆蓋從文章queryset返回的值。 – 2016-10-04 08:55:01

相關問題