2012-03-22 34 views
1

我有一個沙盒,其中包含大量由一個或多個屬性組成的項目。每個屬性都屬於一個特定的屬性類型(如顏色,形狀等) 我對如何渲染帶有屬性的屬性以及它們的屬性類型的表現感到迷茫。通過輸入形式對很多選項進行分組

模型

class Sandbox(models.Model): 
    item = models.ForeignKey('Item') 

class Item(models.Model): 
    name = models.CharField() 
    sandbox = models.ForeignKey(Sandbox) 
    attributes = models.ManyToManyField('Attribute') 

class Attribute(models.Model): 
    name = models.CharField() 
    type = models.ForeignKey('AttributeType') 

class AttributeType(models.Model): 
    name = models.CharField() 

class ItemAttribute(models.Model): 
    # intermediary model to hold references 
    item = models.ForeignKey(Item) 
    type = models.ForeignKey(AttributeType) 
    attribute = models.ForeignKey(Attribute) 

的ModelForm

class Sandbox(ModelForm): 
    class Meta: 
     model = Sandbox 

只能有每個屬性類型一個選擇。例如,東西只能有一種顏色 或一種形狀。

AttributeType Attribute  Users choice 
    color 
        red 
        blue   [x] 
        green 
        shape 

    shape 
        triangular 
        squared   [x] 
        spherical 

這是我被卡住了。如何在窗體中將這些屬性組合在一起,以及如何使用單選按鈕爲每種類型只選擇一個屬性? 也許我最初有一個簡單的模型表示的想法在這裏短暫? 我已經嘗試過文檔,StackOverflow和谷歌,但沒有運氣。

歡迎任何提示和想法。

我的解決方案

我建立了滿足我的需求的解決方案。 @bmihelac指出我在這篇文章的一個很好的方向,就是如何創建一個創建自定義表單的工廠方法。 [見下文]

def make_sandbox_form(item): 

    def get_attributes(item): 
     item_attributes = ItemAttribute.objects.filter(item=item) 
     # we want the first attribute type 
     _attr_type = item_attributes[0].attribute.all()[0].attribute_type 

     choices = []  # holds the final choices 
     attr_fields = {} # to hold the final list of fields 
     for item_attrs in item_attributes.all(): 
      attributes = item_attrs.attribute.all().order_by('attribute_type') 
      for attr in attributes: 
       print attr.attribute_type, ' - ' , _attr_type 
       if attr.attribute_type == _attr_type: 
        choices.append((attr.pk, attr.value)) 
       else: 
        d = {u'%s' % _attr_type : fields.ChoiceField(choices=choices, widget=RadioSelect)} 
        attr_fields = dict(attr_fields.items() + d.items()) 
        # set the _attr_type to new type and start over with next attribute type 
        _attr_type = attr.attribute_type 
        choices = [] 

     return attr_fields 

    form_fields = { 
     'item' : fields.IntegerField(widget=HiddenInput), 
    } 
    form_fields = dict(form_fields.items() + get_attributes(item).items()) 

    return type('SandboxForm', (forms.BaseForm,), { 'base_fields' : form_fields}) 

調用形式我調用此工廠方法爲: 形式= make_sandbox_form()

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

(我希望我能給予好評所有,但作爲一個StackOverflow的菜鳥我缺乏聲望如此。)

+1

你是否看了['regroup'(https://docs.djangoproject.com/en/dev/ref/templates/builtins/? from = olddocs#regroup)模板標記(允許您按屬性分組) – 2012-03-22 15:22:17

+0

是的,我找不到使用表單實現它的方法,只能使用查詢集。我在想,這個問題可以通過製作一個新的表單渲染方法來解決......問題是如何...... – droidballoon 2012-03-22 15:29:35

回答

1

一個沙箱可以有多個項目,或一個項目有很多沙箱?一件物品是否可以同時屬於多個沙箱?

我想你想一個沙箱中包含很多項目:

class Sandbox(models.Model): 
    name = models.CharField() 

class Item(models.Model): 
    name = models.CharField() 
    sandbox= models.ForeignKey(Sandbox) 
    attributes = models.ManyToManyField('Attribute') 

同樣分析認爲這裏真:

是否一個屬性有許多屬性類型,或一個屬性類型有很多屬性?

在這裏你有關係吧,我剛換的車型

class AttributeType(models.Model): 
    name = models.CharField() 

class Attribute(models.Model): 
    name = models.CharField() 
    type = models.ForeignKey(AttributeType) 

的順序,使每個項目都有一個屬性,他們總是被賦予了這些屬性,顏色和形狀。

雖然你可以有一個表,有一個看起來像數據:

pk type 
1 green 
2 circular 
etc 

我個人不會那樣做,因爲我認爲數據在邏輯上是應該組合在一起一樣。形狀具有與顏色不同的屬性。例如,爲了說明我的觀點,如果你想要一種顏色的RGB,該怎麼辦?然後,如果不需要這些形狀,那麼就會有多餘的形狀列,這很容易混淆。反過來也是如此,顏色沒有尺寸。

相反,我可能會做這樣的事情:

class Color(models.Mode): 
    #info about colors 

class Shape(models.Mode): 
    #info about shapes 

class Item(models.Model): 
    name = models.CharField() 
    sandbox= models.ForeignKey(Sandbox) 
    color= models.ForeignKey(Color) 
    shape= models.ForeignKey(Shape) 

這也保證你只有每選擇,因爲在ForeignKey的默認django.Forms你到ChioceField(IIRC)。

至於從而覆蓋並使其成爲一個單選按鈕,只需查看文檔在這裏:

https://docs.djangoproject.com/en/dev/ref/forms/widgets/

+0

是的,你的銳利眼睛注意到我錯過了Item到Sandbox的引用。更新我的問題。謝謝!關鍵是我無法爲每種類型創建單獨的模型,因爲它們將通過管理界面添加到用戶中。 AttributeTypes的數量可能超出我最初的想法。 – droidballoon 2012-03-22 15:24:25

+1

@droidballoon你仍然可以將它們分開並將數據輸入推送給用戶。如果顏色不存在,只需給他們一個選項來創建一個新的顏色/形狀。 – 2012-03-22 15:47:51

+0

確實,我的意思是,如果用戶想要創建一個新的AttributeType,比如說'聲音',那麼開發人員必須爲此AttributeType創建一個新模型以適應這種變化。或者我錯過了什麼? – droidballoon 2012-03-22 16:04:34

相關問題