基于变量属性的Django表单

时间:2016-10-24 12:53:50

标签: python forms dynamic nested parent

好吧,我一直在努力解决这个问题,我现在无法弄清楚我应该如何在Python / Django中做到这一点。也许我的数据库存在根本性的错误。在这种情况下,请帮助。

这是一个包含我的数据库结构的打印屏幕:https://gyazo.com/bcb0c1090a005c581f3a62ba24d9302e

注意,一个程序可以有任意数量的Chars(特征),每个Chars可以拥有任意数量的猫(类别)。

现在,在这个特定的测试程序中,我想通过表单添加风险。此风险需要回答所有Chars,并为每辆车选择一辆Cats。 (测试风险1:{占用:农场,建筑:金属框架,洒水器:是,防护等级:1})

我该怎么做?

到目前为止,这是我对风险的Python代码:

def add_new_risk(request, id=None):
program = get_object_or_404(Program, id=id)
new_risk_form = NewRiskForm(request.POST or None)
if new_risk_form.is_valid():
    new_risk = new_risk_form.save(commit=False)
    new_risk.save()
    return HttpResponseRedirect(program.get_absolute_url() + 'risks/create/' + str(new_risk.id))
context = {
"form": new_risk_form
}
return render(request, 'form.html', context)

首先,我选择要添加风险的程序,然后,我需要回答该程序中包含的所有特征。我试过这个:

def answer_risk_chars(request, id=None, program_id=None):
program = get_object_or_404(Program, id=program_id)
risk = RiskClass(program=Program.objects.get(id=program.id))
chars = program.char_set.all()
for c in chars:
    setattr(risk, c.label, models.CharField(max_length=200, choices=c.cat_set.all(), default=c[0]))

但是,我不知道如何构建基于'risk'的表单,该表单应该包含所有正确的属性。我甚至不知道这是否可能。

有没有办法做到这一点?

提前致谢

1 个答案:

答案 0 :(得分:0)

答案是肯定的。您可以在运行时动态构造任何Django表单或其他实体,而不是作为声明性类。你可能会发现在这里仔细阅读我自己回答的问题很有用How to reduce Django class based view boilerplate。它不是关于形式的,而是对如何从Django风格的声明class到动态构造同一事物的完全阐述。

如果你谷歌“Django动态表单”,你会发现更多与表单相关的东西。您可能会发现您所需要的已经完成(尝试搜索Django软件包网站)。

如果你需要自己动手,你需要阅读并重新阅读Python的type内置的三参数形式的(非常简短的)文档,它构造了类。然后你会尝试像

这样的东西
MyDynamicFormClass  = type( 'MyDynamicForm', (forms.Form, ), dict_of_fields)

其中dict_of_fields可能构造类似(不完整,大纲代码):

dict_of_fields = {}

for cat in cats:
    choices = [ ]
    for char in get_characteristics( cat):
        choices.append( (db_value_for_char, user_label_for_char) )

    dict_of_fields[ cat_name ] = forms.ChoiceField( choices, ...)    

如果所有这些表单都有一组相同的字段,则可以从MyBaseForm继承而不是从forms.Form继承它们。还有一些众所周知的修改MyBaseForm实例的方法是在运行时添加额外的字段,而不是从零开始创建一个全新的类。

相关问题