2013-05-06 58 views
1

所以,這裏是我的問題:我試圖生成一大堆特性的一個大表格,其中一些如果他們是布爾值,一些用文本填充,一些用JS微調器增加或減少。但是,這裏是捕獲,所有這些都是用戶生成的。我所做的是:在某些時候,我邀請用戶通過向模型Option添加對象來創建它的特性,其中他告訴我特性的名稱和它的類型(布爾,文本或數字)。使用Django Formset從多個模型生成動態表單

這裏是我的簡化模型:

class Characteristic(models.Model): 
     option = models.ForeignKey('Option') 

    class Option(models.Model): 
     option_name = models.CharField(max_length=100) 
     OPTION_TYPE_CHOICES = (
      ('B',u'Bolean'), 
      ('T',u'Textual'), 
      ('N',u'Numerical'), 
    ) 
     option_type = models.CharField(max_length=1,choices=OPTION_TYPE_CHOICES) 

    class Boolean(Characteristic): 
     value = models.BooleanField() 

    class Textual(Characteristic): 
     value = models.CharField(max_length=100) 

    class Numerical(Characteristic): 
     value = models.PositiveIntegerField() 

到目前爲止,一切都很好。

當生成具有所有可能特徵的表單時,問題就開始了。我所做的是這樣的:

這是我的觀點:

@login_required 
def AddCharacteristic(request): 

    numerical_options = Option.objects.filter(option_type='N') 
    textual_options = Option.objects.filter(option_type='T') 
    boolean_options = Option.objects.filter(option_type='B') 

    NumericalFormset = modelformset_factory(Numerical,extra=len(numerical_options)) 
    TextualFormset = modelformset_factory(Textual,extra=len(textual_options)) 
    BooleanFormset = modelformset_factory(Boolean,extra=len(boolean_options),form=forms.BooleanForm) 

    if request.method == 'POST': 
     numerical_formset = NumericalFormset(request.POST,prefix='numerical')· 
     textual_formset = TextualFormset(request.POST,prefix='textual') 
     boolean_formset = BooleanFormset(request.POST,prefix='boolean') 
     if numerical_formset.is_valid() and textual_formset.is_valid() and boolean_formset.is_valid(): 
      numerical_formset.save() 
      textual_formset.save() 
      boolean_formset.save() 
     if 'next' in request.GET: 
      return HttpResponseRedirect(request.GET['next']) 
     else: 
      return HttpResponseRedirect('../../list/') 
    else: 
     boolean_formset = BooleanFormset(queryset=Boolean.objects.none(),prefix='boolean',initial=[{'option':n.id} for n in boolean_options]) 
     textual_formset = TextualFormset(queryset=Textual.objects.none(),prefix='textual',initial=[{'option':n.id} for n in textual_options]) 
     numerical_formset = NumericalFormset(queryset=Numerical.objects.none(),prefix='numerical',initial=[{'option':n.id} for n in numerical_options]) 
    return render_to_response('characteristics/add.html', { 
     'numerical_formset': numerical_formset, 
     'textual_formset': textual_formset, 
     'boolean_formset': boolean_formset, 
    },context_instance=RequestContext(request)) 

在我看來:

<form method="post"> 

    {% csrf_token %} 

    {{ numerical_formset.management_form }} 
    {% for numerical_form in numerical_formset %} 
    {{ numerical_form }}<br> 
    {% endfor %} 

    {{ boolean_formset.management_form }} 
    {% for boolean_form in boolean_formset %} 
    {{ boolean_form }}<br> 
    {% endfor %} 

    {{ textual_formset.management_form }} 
    {% for textual_form in textual_formset %} 
    {{ textual_form }}<br> 
    {% endfor %} 
    <button type="submit">Save</button> 
    <button type="reset">Cancel</button> 
</form> 

因此,它是一種工作,但主要的問題至今:

  • 我無法重寫小部件,將特徵選項字段從下拉列表轉換爲標籤。
  • 確認工作。如果用戶在數字字段中或其他方式放置文本,Django它不抱怨。
  • 一般的感覺,我搞砸了完全和工程的東西。 :)

回答

1

它看起來像你試圖創建自己的實現EAV。你可能想用django-eav代替。

如果你仍然想要自己的方式,你可以使用​​作爲參考。

此外,Django的主要開發人員之一Jacob Kaplan-Moss撰寫了一篇名爲「Dynamic form generation」的文章(文章發表於2010年,但截至今日,所述解決方案仍在工作) 。

還有其他方法來存儲和檢索動態數據(如django-hstoredjango-mutant)。我已經written關於他們before

+0

作爲旁註:還有一個名爲'django-hstore-flattenfields'的應用程序,它使用[hack](https://github.com/multmeio/django-hstore-flattenfields/blob/master/hstore_flattenfields/models .py)使Django [生成](https://github.com/multmeio/django-hstore-flattenfields/blob/master/hstore_flattenfields/forms.py)動態表單,就好像它們是'ModelForm'一樣。 – 2013-05-06 15:34:53