Javascript 使用多个单选按钮模拟多个ManyToManyField
DjangoJavascript 使用多个单选按钮模拟多个ManyToManyField,javascript,django,Javascript,Django,DjangoManyToManyField在HTML中呈现如下内容: <form action="" method="post"> <select name="answers" multiple="multiple"> <option value="1" >Question 1, Answer 1</option> <option value="2">Question 1, Answer 2</option&g
ManyToManyField
在HTML中呈现如下内容:
<form action="" method="post">
<select name="answers" multiple="multiple">
<option value="1" >Question 1, Answer 1</option>
<option value="2">Question 1, Answer 2</option>
<option value="3">Question 1, Answer 3</option>
<option value="4">Question 2, Answer 1</option>
<option value="5">Question 2, Answer 2</option>
</select>
<input type="submit">
</form>
它实际上不允许用户一次选择多个单选按钮。另一方面,如果我将单选按钮命名为answers[0]
和answers[1]
,则在POST中,它会发送两个具有这些名称的独立实体,而不是发送组合的answers
我这样问是因为在后端,我有一个DjangoManyToManyField
和一个带有自定义小部件的ModelForm
,我正试图从这个自定义小部件将数据保存到ManyToManyField
,而不必在后端使用太多的技巧,但我不断收到错误“输入值列表”
编辑:JavaScript是可以接受的,只要它不发送原始数据,就像Django继承/自定义解析一样
编辑2:这是我的ManyToManyField小部件
{% if questions %}
{% for question in questions %}
<fieldset>
<legend>{{ question.question }}</legend>
{% if question.options %}
{% for option in question.options %}
<input type="checkbox" class="form-check-input" name="answers" id="id_{{ option.id }}" value="{{ option.id }}">
<label for="id_{{ option.id }}">{{ option.text }}</label>
<br>
{% endfor %}
{% else %}
<p>No options for this question.</p>
{% endif %}
</fieldset>
{% endfor %}
{% else %}
<p>No questions in test.</p>
{% endif %}
{%if-questions%}
{问题%中的问题的百分比}
{{question.question}}
{%if question.options%}
{%用于有问题的选项。选项%}
{{option.text}
{%endfor%}
{%else%}
这个问题没有选择
{%endif%}
{%endfor%}
{%else%}
考试中没有问题
{%endif%}
它实际上不允许用户同时选择多个单选按钮
一旦另一方面,如果我命名单选按钮,则回答[0]和
答案[1],在POST中,它发送两个具有这些名称的独立实体
而不是发送组合答案
这并不能满足您的需求,但至少可以解决一个谜团。当您使用answers[]
作为名称时,后端会将其识别为数组并将所有值加入到数组中。这可用于除single(单选/单选)之外的任何输入类型
这是您可以使用的js解决方案,但您的情况表明,您使用的模型并不适合这种情况。当然,它可以像贝娄一样通过黑客的方式解决,但当你遇到这段代码时,你总是需要解决一些变通办法
所以我的建议是:改变后端的方法
document.getElementById('answers')。onsubmit=function(e){
e、 preventDefault();//防止提交;
设clone=this.cloneNode(true);
让inputs=clone.querySelectorAll('input[type=radio]');
让formData=newformdata(克隆);//HTML5
//检查有效性
if(Array.from(formData.values()).length!=clone.querySelectorAll('fieldset').length){
警报('无效表单!')
返回false;
}
对于(设i=0;i将单选按钮更改为复选框应允许您选择多个值
<form action="" method="post">
<fieldset>
<legend>Question 1</legend>
<input name="answers" id="id_1" value="1" type="checkbox">
<label for="id_1">Answer 1</label>
<br>
<input name="answers" id="id_2" value="2" type="checkbox">
<label for="id_2">Answer 2</label>
<br>
<input name="answers" id="id_3" value="3" type="checkbox">
<label for="id_3">Answer 3</label>
<br>
</fieldset>
<fieldset>
<legend>Question 2</legend>
<input name="answers" id="id_4" value="4" type="checkbox">
<label for="id_4">Answer 1</label>
<br>
<input name="answers" id="id_5" value="5" type="checkbox">
<label for="id_5">Answer 2</label>
<br>
</fieldset>
</form>
问题1
答复1
答复2
答复3
问题2
答复1
答复2
此表单生成的HTTP POST应该与您在上面给出的带有select
标记的示例完全相同。我认为您可以尝试使用CheckBox,如果您可以将其转换为Django 1.11.8中支持的完整答案,我将为您提供奖励。answers[]
是一个特定于PHP的东西,我试过了,但它与Django不起作用。我今天回家后会尝试你的Javascript解决方案。如果你告诉我怎么做,我可以改变方法。现在我有一个测试表,其中有问题,每个问题都有多个选项(问题作为fk)还有一个带有测试fk的测试结果表,还有很多答案。我专注于前端,所以我对db模型的知识非常有限。也许其他人可以给你正确的建议。但我已经做了一些Q/a调查,可以说从来没有必要使用这样的模型。看起来给他们不同的名字并不会合并到t中后端的ManyToManyField
。@Hameer Abbasi Javascript将它们合并到答案中。第一个示例(未注释):1)用户选择单选按钮2)用户提交表单3)js阻止提交并创建克隆表单4)在此克隆表单中js将类型替换为复选框并为答案[]命名(或答案-尝试两者)5)然后js触发这个克隆的提交是的,但是我也可以选择多个为一个答案。它看起来不像一个单选按钮。
<form action="" method="post">
<fieldset>
<legend>Question 1</legend>
<input name="answers" id="id_1" value="1" type="checkbox">
<label for="id_1">Answer 1</label>
<br>
<input name="answers" id="id_2" value="2" type="checkbox">
<label for="id_2">Answer 2</label>
<br>
<input name="answers" id="id_3" value="3" type="checkbox">
<label for="id_3">Answer 3</label>
<br>
</fieldset>
<fieldset>
<legend>Question 2</legend>
<input name="answers" id="id_4" value="4" type="checkbox">
<label for="id_4">Answer 1</label>
<br>
<input name="answers" id="id_5" value="5" type="checkbox">
<label for="id_5">Answer 2</label>
<br>
</fieldset>
</form>