【发布时间】:2012-03-22 14:44:32
【问题描述】:
我有一个沙盒,其中包含大量由一个或 更多属性。每个属性都属于特定的属性类型(例如颜色、形状等) 我不知道如何使用与它们的 AttributeTypes 分组在一起的属性来呈现表单。
型号
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)
模型表单
class Sandbox(ModelForm):
class Meta:
model = Sandbox
每个属性类型只能有一个选择。例如,某物只能有一种颜色 或一种形状。
AttributeType Attribute Users choice
color
red
blue [x]
green
shape
shape
triangular
squared [x]
spherical
这是我卡住了。如何在表单中将这些属性组合在一起,如何使用单选按钮为每种类型选择一个属性? 也许我最初的想法是有一个简单的模型表示在这里不够? 我尝试过文档、StackOverflow 和 Google,但没有运气。
欢迎任何提示和想法。
我的解决方案
我建立了一个满足我需求的解决方案。 @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})
调用我调用这个工厂方法的表单: form = make_sandbox_form()
http://www.b-list.org/weblog/2008/nov/09/dynamic-forms/
(希望除了作为 StackOverflow 新秀之外的所有人都可以投票,但我没有这样做的声誉。)
【问题讨论】:
-
你看过
regroup模板标签(允许你按属性分组) -
是的,我做到了,但我找不到使用表单实现它的方法,只能使用查询集。我在想的是,这个问题可以通过制作一个新的表单渲染方法来解决......问题是如何......
标签: django django-models django-forms