基于变量属性的Django Form
Django Form Based on Variable Attributes
好吧,我已经为此苦苦挣扎了一段时间,我真的不知道我应该如何在 Python / Django 中做到这一点。也许我的数据库存在根本性的错误。在这种情况下,我们将不胜感激。
这是包含我的数据库结构的打印屏幕:https://gyazo.com/bcb0c1090a005c581f3a62ba24d9302e
注意,一个程序可以有任意数量的字符(特征),每个字符可以有任意数量的猫(类别)。
现在,在这个特定的测试程序中,我想通过表单添加风险。这个风险需要回答所有的字符,并为每辆汽车选择一只猫。 (测试风险 1:{占用:农场,建筑:金属框架,洒水器:是,保护 Class: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' 的表单,它应该包含所有正确的属性。我什至不知道这是否可能。
有什么办法吗?
提前致谢
答案是"yes"。您可以在运行时动态构建任何 Django 表单或其他实体,而不是作为声明 class。您可能会发现在此处 How to reduce Django class based view boilerplate 仔细阅读我的自我回答问题很有用。它与表单无关,但它非常完整地阐述了如何从 Django 风格的声明式 class
到同一事物的动态构造。
如果你 google "Django dynamic form" 你会发现更多与表单相关的东西。您可能会发现您需要的已经完成(尝试搜索 Django 包网站)。
如果你需要自己滚动它,你需要阅读并重新阅读 Python 的 type
内置函数的三参数形式的(非常简短的)文档,它构造classes。然后你会尝试像
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 的实例以在运行时添加额外的字段,而不是从无到有地创建一个全新的 class。
好吧,我已经为此苦苦挣扎了一段时间,我真的不知道我应该如何在 Python / Django 中做到这一点。也许我的数据库存在根本性的错误。在这种情况下,我们将不胜感激。
这是包含我的数据库结构的打印屏幕:https://gyazo.com/bcb0c1090a005c581f3a62ba24d9302e
注意,一个程序可以有任意数量的字符(特征),每个字符可以有任意数量的猫(类别)。
现在,在这个特定的测试程序中,我想通过表单添加风险。这个风险需要回答所有的字符,并为每辆汽车选择一只猫。 (测试风险 1:{占用:农场,建筑:金属框架,洒水器:是,保护 Class: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' 的表单,它应该包含所有正确的属性。我什至不知道这是否可能。
有什么办法吗?
提前致谢
答案是"yes"。您可以在运行时动态构建任何 Django 表单或其他实体,而不是作为声明 class。您可能会发现在此处 How to reduce Django class based view boilerplate 仔细阅读我的自我回答问题很有用。它与表单无关,但它非常完整地阐述了如何从 Django 风格的声明式 class
到同一事物的动态构造。
如果你 google "Django dynamic form" 你会发现更多与表单相关的东西。您可能会发现您需要的已经完成(尝试搜索 Django 包网站)。
如果你需要自己滚动它,你需要阅读并重新阅读 Python 的 type
内置函数的三参数形式的(非常简短的)文档,它构造classes。然后你会尝试像
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 的实例以在运行时添加额外的字段,而不是从无到有地创建一个全新的 class。