django - 验证 Django 运行时生成的表单字段信息
问题描述
我正在尝试创建一个在运行时生成带有其字段的表单的过程。此表格是简单表格,而不是模型表格。它包含许多 RadioSelect 字段、一个 TextArea 和一个 IntegerField。将生成的单选按钮字段的数量由从数据库表中获取的数据决定。数据采用 JSON 格式,解析时包含字典列表,如下所示:
[
{'criteria': 'design', 'description': 'aaa, bbb'},
{'criteria': 'design', 'description': 'ccc, ddd'},
{'criteria': 'design', 'description': 'eee, fff'},
{'criteria': 'design', 'description': 'ggg, hhh'},
{'criteria': 'design', 'description': 'iii, jjj'},
{'criteria': 'design', 'description': 'kkk, lll'},
]
在上面的示例中,有 6 个字典,这意味着将生成 6 个 RadioSelect 字段。如果 JSON 数据包含 10 个字典,则将生成 10 个 RadioSelect 字段。TextArea 和 IntegerField 字段始终存在于表单中。
提交表单时,我想验证表单,如果没有错误,则从表单中获取数据,对数据执行一些操作,将数据保存在不同的数据库表中,并使用保存的数据显示表单。如果有错误,则显示出现错误的表单。
我想只使用一个视图和一个模板来编写这个过程。这是我的代码的简化摘录
表格.py
class ExampleForm(forms.Form):
def __init__(self, *args, **kwargs):
radio_choices = (
('0', '0'),
('1', '1'),
('2', '2'),
('3', '3'),
('4', '4'),
)
ratings = kwargs.pop('rating')
super(ExampleForm, self).__init__(*args, **kwargs)
if isinstance(ratings, QueryDict):
self.ratings = ratings.dict()
# stuck here
else:
self.ratings = ratings
# loop through the dict and create radio button for each of them
for idx, rating in enumerate(self.ratings, start=1):
field = forms.TypedChoiceField(
label=rating["criteria"],
choices=radio_choices,
coerce=lambda x: bool(int(x)),
widget=forms.RadioSelect,
initial=0,
required=False,
)
self.fields["criteria{}".format(idx)] = field
self.fields["details"] = forms.CharField(
label="Details",
# max_length=80,
required=False,
widget=forms.Textarea(attrs={
'placeholder': 'Type any other impressions you have',
}),
help_text='Write any message here',
)
self.fields["overall_evaluation"] = forms.IntegerField(
label="Overall Evaluation",
max_value=4,
min_value=0,
required=True,
)
视图.py
from .models import Rating, Result
def formtest(request):
if request.method == "POST":
# request.POST contains a QueryDict which is immutable
# To get a mutable object call the copy() method on request.POST??
ratingform = ExampleForm(rating=request.POST or None) # fails here
# call is_valid here??
# Process data
# Save data in Result
else:
rating = Rating.objects.get(pk=4).criteria
ratingform = ExampleForm(rating=json.loads(rating))
return render(request, 'formtest.html', context={
'form': ratingform,
})
第一次访问表单时,我可以毫无问题地创建表单,但是在提交表单后,我不仅会收到错误消息,而且我认为我将无法为 RadioSelect 字段生成标签。
我认为原因是 QueryDict 中的数据与request.POST
从数据库表中获取的原始字典列表的形式不同。这是request.POST
看起来的样子
<QueryDict: {'csrfmiddlewaretoken': ['sfdgbif'], 'criteria1': [
'0'], 'criteria2': ['0'], 'criteria3': ['0'], 'criteria4': ['0'], 'criteria5': ['0'], 'criteria6': ['0'], 'details': ['very good product'], 'overall_evaluation': ['3']}>
键 ,与原始字典列表中criteria1..criteria6
的键不同criteria
,它们仅包含数字,即在提交表单之前从单选按钮中选择的值。一种方法可能是修改 QueryDict 但我不知道这是否是一个好方法。
如何使用 request.POST 数据重新创建表单并检查表单在提交时是否有效?
解决方案
我想到了。我没有将 POST 值传递给表单,而是将其作为表单的**kwargs
参数传递,这是完全错误的。因此,无法验证表单。一次代码更改解决了我的问题。
ratingform = ExampleForm(request.POST, rating=interview_rating)
推荐阅读
- php - 向我的 xml 文件发送发布请求时无法接收响应
- java - 文本观察器,擦除 将文本向左移动
- python - 确保 pyinstaller 使用 Python 2.7 运行
- winforms - 表单字符在运行时未正确显示 - VS Code PowerShell
- node.js - 用户登录时更改用户密码,但我收到错误“位置 0 处 JSON 中的意外令牌 o”
- git - 切换分支时如何rebase fork repo?
- binary - 剩余的积分松弛整数线性规划
- java - 如何使用 Java SWT .setBackground() 方法
- sql - 如何使用 sp_MSforeachdb
- java - 如何加载 org.springframework.jdbc.core.RowMapper 库