这不是您问题的确切答案,但我做了类似的事情,我认为可能对您有用。我创建了一个完全可自定义的表单,以便最终用户可以自定义表单。
我最终得到了 2 个模型,一个 BuiltForm 和一个 BuiltFormField:
class BuiltForm(models.Model):
name = models.CharField(max_length=32)
def form(self, data=None, initial=None):
form = BuiltFormGenericForm(data, initial=initial)
form.addBuiltFormFields(BuiltFormField.objects.filter(builtform=self, disabled=0))
return form
class BuiltFormField(models.Model):
builtform = models.ForeignKey(BuiltForm)
type = models.CharField(max_length=32, choices=ALL_FIELD_TYPES)
label = models.CharField(max_length=32)
fieldname = models.CharField(max_length=32)
helptext = models.CharField(max_length=256, blank=True)
required = models.BooleanField(default=False)
sort_order = models.IntegerField(default=0)
disabled = models.BooleanField(default=False)
options = models.TextField(blank=True)
def field(self):
field = ALL_FIELD_MAPS.get(self.type)
## Build out the field, supplying choices, `required`, etc.
有几件事是不正常的。 ALL_FIELD_TYPES 是表单中允许的字段类型的映射。这与dict() 结合使用,以识别该字段应使用哪个类(CharField、EmailField、ChoiceField 等)。 options 也是 pickled 选项列表,供以后在 ChoiceField 中使用。这使我可以创建任意选项列表,而无需单独调用数据库。
另一个主要部分是自定义Form 类,它允许使用BuiltForm 中的字段填充自身。我的看起来像这样:
class BuiltFormGenericForm(forms.Form):
built_form_fields = {}
builtform = None
def addBuiltFormFields(self, fields):
for field in fields:
self.fields[field.label] = field.field()
self.built_form_fields[field.pk] = field
def is_valid(self):
# Do validation here. My code for this is pretty big because of custom fields
# and calculations that I have to squeeze in.
BuiltFormField 对象并非设计为通过管理界面创建,而是通过使用大量 JavaScript 的自定义对象创建,以使其对用户友好,但您当然可以公开 BuiltFormField 模型的部分内容在管理界面中进行更新。
希望这可以帮助您为表单制定模型。