[英]Creating Django form questionnaire with radio buttons
我正在尝试在我的 django 应用程序中实施一项调查。 目前,我通过手动为表单结构绘制 HTML 来实现它,如下所示:
<!-- Question 1-->
<form method="post" action="{% url 'piuserform' %}">
{% csrf_token %}
<div class="mx-auto">
<h3 class="mb-4">At the time of the accident, the injured party was: </h3>
<label class="radcontainer">The driver of an automobile.
<input type="radio" name="question1" value="The driver of an automobile">
<span class="checkmark"></span>
</label>
<label class="radcontainer">The passenger of an automobile.
<input type="radio" name="question1" value="The passenger of an automobile">
<span class="checkmark"></span>
</label>
<label class="radcontainer">A pedestrian.
<input type="radio" name="question1" value="A pedestrian">
<span class="checkmark"></span>
</label>
</div>
<!-- /Question 1 -->
<!-- question 3-->
<div class="mx-auto pt-5">
<h3 class="mb-4">How many vehicles were involved in the accident?</h3>
<label class="radcontainer">One
<input type="radio" name="question3" value="One">
<span class="checkmark"></span>
</label>
<label class="radcontainer">Two
<input type="radio" name="question3" value="Two">
<span class="checkmark"></span>
</label>
<label class="radcontainer">Three
<input type="radio" name="question3" value="Three">
<span class="checkmark"></span>
</label>
<label class="radcontainer">Four or more
<input type="radio" name="question3" value="Four or more">
<span class="checkmark"></span>
</label>
</div>
<!-- /Question 3 -->
现在我尝试使用 Django forms api 来实现这种效果,但它只会呈现最后一个问题。 问卷都是单选按钮,答案字段变化很大。 有没有办法自动化这个,所以我可以通过 modelForm 或 Formsetfactory 使用 {{form}} 渲染? 我查看了许多文档,但没有一个对我的问题非常清楚,当我尝试实现 forms api 时,就像我说的那样,它只会提出一个问题。 非常感谢帮助
编辑:
当我尝试实现 forms API 时,我使用了这种方法:
forms.py
blah_choices = [("1", "first"), ("2", "second")]
blah_choices2 = [("3", "third"), ("4", "four")]
class testRadioQuestions(forms.Form):
q1 = forms.ChoiceField(label="Blah blah blah form question",
choices=(blah_choices),
widget=forms.RadioSelect()),
q2 = forms.ChoiceField(label="blah blah some more form question",
choices=(blah_choices2),
widget=forms.RadioSelect())
看法
def other_questionnaire(request):
if request.method == "POST":
print(request.body)
return render(request, 'website/otherQuestions.html', {'form': form})
这看起来工作量很大。 我认为问题可能是您的视图上下文只有最后一种形式。 您将需要创建 forms 的列表或字典。 您还需要使用“ 前缀”来区分他们的“id”。
我想出了一个解决方案,但是(就像你一样,我想)我有一种挥之不去的感觉,我错过了“表格”api 中的一些重要内容。
我的解决方案是手动为每个表单分配一个前缀,这样我就可以将它从 POST 解压到正确的表单子类中。 我不会发布所有不同的部分,但这里有一个草图:
# forms.py
AnswerMap = { question_answer_type1 : FormClass1, etc etc }
def form_get(question, instance=None):
answerform = AnswerMap[question.answer_type](instance=instance) # not sure this works, may need to handle two cases separately.
return answerform
def form_post(question, data, instance=None):
answerform = AnswerMap[question.answer_type](data=data, instance=instance)
if answerform.is_valid():
return answerform
else:
pass # handle error, I guess.
下一部分是视图。 我 go 通过 request.POST 的方式在这里似乎效率很低,因为我通过两次 go - 首先收集前缀并找出存在哪些问题,然后第二次(在单一理解中)收集每个前缀的数据。 但我还没有想出更好的办法。
# views.py
class page_view(View):
def get(self, page_no):
forms = {}
questions = Question.objects.filter(page=page_no)
for question in questions:
forms[question] = get_form_for_question(question, prefix=('q'+question.pk))
self.context['forms'] = forms
return render(request, template, context)
def post(self, page_no)
prefixes = []
self.form_items = {}
for key, value in request.POST.items():
if key.startswith("q"):
q_number = re.search(r'q(\d+)#', key)
pk_q = int(q_number.group(1)) # the digits are the question primary key
prefix = 'q' + str(pk_q)
if prefix not in prefixes:
prefix.append(prefix)
question = Question.objects.get(pk=pk_q)
self.form_items[prefix] = {key: val for key,val in request.POST.items() if prefix in key} # collects data for form; add any data that you don't render but will need in the database somewhere here - e.g. username or timestamp
form = form_post(value=self.form_items[prefix], question=question)
if form.is_valid():
form.save()
return HttpRedirectResponse('as appropriate')
添加自定义模板标签以解压模板中的表单:
# custom_tags.py
@register.filter
def get_item(dictionary, key):
return dictionary.get(key)
在模板中,提取所需的表单,如下所示:
{% load 'custom_tags' %}
{% for question in page_question_set %}
{{question}}
{{ forms|get_item:question }}
{% endfor %}
希望这个对你有帮助。 我不认为这是一个糟糕的解决方法,但我仍然担心我正在解决框架实际上可以处理的问题。
只需删除每个已定义字段末尾的 <,>(逗号),这应该可以
forms.py
from django import forms
blah_choices = [("1", "first"), ("2", "second")]
blah_choices2 = [("3", "third"), ("4", "four")]
class TestRadioQuestions(forms.Form):
email = forms.EmailField()
q1 = forms.ChoiceField(label="Blah blah blah form question",choices=(blah_choices),widget=forms.RadioSelect())
q2 = forms.ChoiceField(label="blah blah some form question",choices=(blah_choices2),widget=forms.RadioSelect())
视图.py
def testRadioQuestions(request):
if request.method == 'POST':
form = TestRadioQuestions(request.POST)
if form.is_valid():
return HttpResponseRedirect('../../url_name')
else:
form = TestRadioQuestions()
return render(request, 'template_url', {'form' : form })
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.