我正在制作一个烧瓶应用程序,基本上是基于形式的,所以我使用WTForms和烧瓶wtf。
我目前正在重构我的代码,因此我的整个表单使用WTForms,其中有一个非常动态的部分我无法使用WTForms实现。我不知道怎么做,我最初的想法不起作用,我找不到关于我的问题的参考资料或教程,所以这就是我寻求帮助的原因。
因此,该表单允许用户提交包含以下内容的对象:
你可以猜到我对名单有意见。现在代码的工作方式是,我使用wtforms获取标签和描述,属性列表是使用一个config常量(在整个代码中使用,所以如果我想添加新属性,我只有一个地方可以编辑)和javascript中的一个动态菜单来创建(这里,用于谓词)字段,然后我可以在view函数中使用flask.request.form对象。谓词的所有隐藏字段都具有相同的name属性,对象的所有隐藏字段都具有相同的name属性。
以下是表单视图的外观,由几个属性初始化:
http://i.imgur.com/bfMG95s.png
在“Propriétés”标签下,您有一个下拉列表来选择谓词,第二个字段根据所选谓词显示或隐藏(可以是下拉列表或文本字段),只有当您单击“ajuter Propriété”(“添加属性”)时,才会在下面的选项卡中添加新行并生成字段。
我不想改变这方面的任何东西,因为它的工作非常好,使形式非常直观,基本上正是我希望它是从用户端。
这就是我的自定义表单现在的样子(它不起作用,无论我提交表单的字段数是多少,属性都保持为空):
class PropertyForm(Form):
property_predicate = HiddenField(
validators=[AnyOf(values=app.config["PROPERTY_LIST"].keys())]
)
property_object = HiddenField(
validators=[DataRequired()]
)
class CategoryForm(Form):
"""
Custom form class for creating a category with the absolute minimal
attributes (label and description)
"""
label = StringField(
"Nom de la categorie (obligatoire)",
validators=[DataRequired()]
)
description = TextAreaField(
"Description de la categorie (obligatoire)",
validators=[DataRequired()]
)
properties = FieldList(FormField(PropertyForm),validators=[Optional()])
下面是我想在views.py代码(我目前正在重构)中做的事情:
def cat_editor():
cat_form = CategoryForm()
if request.method == "GET":
# Do GET stuff and display the form
return render_template("cateditor.html", form=cat_form, varlist=template_var_list)
else if request.method == "POST":
if cat_form.validate_on_submit():
# Get values from form
category_label = cat_form.label.data
category_description = cat_form.description.data
category_properties = cat_form.properties.data
# Do POST stuff and compute things
return redirect(url_for("index"))
else:
# form didn't validate so we return the form so the template can display the errors
return render_template("cateditor.html", form=cat_form,
template_var_list = template_var_list)
基本结构工作得很好,只是那个该死的动态列表,我不能正常工作。
从WTForms CategoryForm实例获取标签和描述工作正常,但属性始终返回空列表。理想情况下,我希望能够得到一个表单列表[(predicte1,property1),(predicte2,object2)。。。]调用cat_form.properties.data时(这就是为什么我有一个表单字段列表,每个字段中有两个HiddenField),但是只要使用WTForms,就不必从两个列表构建这样的列表。知道吗?非常感谢:)
使用jQuery获取表单中更动态的元素/行为。请注意,表单字段有一个隐藏属性(或方法,具体取决于是否使用bootstrap),允许您呈现可能需要的所有内容,但仅在需要时显示字段,否则隐藏它们。动态添加字段有点困难,但并非完全不可能。与属性关联的字段数是否有限制?如果是的话,我只会渲染最大数量的字段(只要合理,最多5个似乎没问题,当您达到用户可以添加的最大属性数的两位数时,渲染一堆您永远不会使用的字段会变得不雅)。
Here's这是一个很好的地方,可以看看它是如何工作的。当然,您还有一个选择何时隐藏或显示相关字段的问题,但是也可以通过使用jQuery的.change()事件的javascript/jQuery脚本来处理。像这样的:
这段代码可能会不工作,而且肯定缺乏正确的逻辑,但是应该能让您了解如何使用jQuery解决这个问题。请注意,“property1”字段始终存在,等待用户选择正确的下拉值时显示。
我通过使用FieldList对象和append_entry()来发现问题所在,看看如果我要生成一个预填充的属性列表,wtf将生成什么样的HTML代码。
我的Javascript生成了所有同名的隐藏字段,据我所知,WTForms能够聚合同名的字段来创建列表。问题是,那些同名字段是嵌套在FieldList对象名属性中的FormField本身的一部分。
为了让WTForms Form对象区分一组隐藏字段,在FieldList中嵌套Form fields时,它会在FormFields字段名前面加上“FieldList_name-index-”。这意味着WTForms所期望的是
我修改了javascript,以便它生成适当的名称。现在,当我调用cat_form.properties.data时,我得到了如下信息:
这正是我需要的。出于某种原因,表单没有验证,但至少我知道如何使WTForms提取数据,我的javascript生成的隐藏字段,这就是问题所在。
编辑:表单验证之所以发生,是因为必须将CSRF隐藏输入与CSRF一起插入到使用FormField生成的每个子表单中。
相关问题 更多 >
编程相关推荐