我正在努力构建一个多问题测验选项,但我不能让我的PostgreSQL保存正确的数据。数据库只保存第一个选项,而不关心它是否是正确的答案,以及是否有更多的正确答案。
“GET /multi-form/ HTTP/1.1”200 7693 <QueryDict:“csrfmiddlewaretoken”:'ALONiRKNa0QKQe6LQWacVz9vSQZPbFuyfdaLimGg9czBEy46hQAbAGyQatRLpI33'],'question':'“5”],“ans_count”:“5”],“answer_0”:'99'],'answer_1':'98'],'answer_2':'97'],'is_correct_2':请单击“on”],“answer_3”:“Qaz”],“answer_4”:请输入'Dacia'],'is_correct_4':打开“],”提交“:'Senden']}> 5 True ['99','is_correct':错误}]
99被选为唯一的答案,但它是不正确的,我选择了更多正确的选项,因为你可以在屏幕截图上发现。
forms.py(示例网站)
class AddMultipleForm(forms.ModelForm):
ans_count = forms.IntegerField(min_value=1, label="Number of Answers Anzahl der Antworten")
class Meta:
model = MultiQuesModel
fields = ["question", "language_name"]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
ans_count = self.initial.get("ans_count", 1)
for i in range(ans_count):
self.fields[f"answer_{i}"] = forms.CharField(max_length=200, required=True)
self.fields[f"is_correct_{i}"] = forms.BooleanField(
required=False, widget=forms.CheckboxInput(attrs={"class": "checkbox"})
)
def clean(self):
cleaned_data = super().clean()
ans_count = cleaned_data.get("ans_count")
print(ans_count)
answers = []
for i in range(ans_count):
answer_text = cleaned_data.get(f"answer_{i}")
is_correct = cleaned_data.get(f"is_correct_{i}")
if answer_text:
answers.append({"text": answer_text, "is_correct": is_correct})
if not answers:
raise forms.ValidationError(
"Please fill out at least one answer. Bitte füllen Sie mindestens eine Antwort aus."
)
cleaned_data["answers"] = answers
return cleaned_data
Multiformular .html
{% extends 'dependencies.html' %}
{% block content %}
<div class="jumbotron container row">
<div class="col-md-6">
<h1>Add Question</h1>
<div class="card card-body">
<form action="" method="POST">
{% csrf_token %}
{{ form.question.label_tag }} {{ form.question }}
<br>
{{ form.question.label_tag }} {{ form.language_name }}
<label for="id_ans_count">Number of Answers Anzahl der Antworten:</label>
{{ form.ans_count }}
<br>
<div id="answers-container">
{% for i in form.visible_fields %}
{% if 'answer_' in i.name or 'is_correct_' in i.name %}
{{ i.label_tag }} {{ i }}
<br>
{% endif %}
{% endfor %}
</div>
<input type="submit" name="Submit">
</form>
</div>
</div>
</div>
<script>
// JavaScript, um dynamisch Antworten hinzuzufügen
const ansCountInput = document.getElementById("id_ans_count");
const answersContainer = document.getElementById("answers-container");
ansCountInput.addEventListener("change", function () {
const ansCount = parseInt(this.value);
answersContainer.innerHTML = ""; // Leeren Sie das Container-Div
for (let i = 0; i < ansCount; i++) {
const answerField = document.createElement("div");
answerField.innerHTML = `
<label for="id_answer_${i}">Answer ${i+1}:</label>
<input type="text" id="id_answer_${i}" name="answer_${i}" maxlength="200" required>
<label for="id_is_correct_${i}">Is Correct:</label>
<input type="checkbox" id="id_is_correct_${i}" name="is_correct_${i}">
<br>
`;
answersContainer.appendChild(answerField);
}
});
</script>
{% endblock %}
models.py(示例网站)
class MultiQuesModel(models.Model):
question = models.CharField(max_length=200, null=True)
answers = models.ManyToManyField("Answer", through="QuestionAnswer")
language_name = models.ForeignKey(Category, on_delete=models.CASCADE)
def __str__(self):
return self.question
# Two fields possible
class Answer(models.Model):
text = models.CharField(max_length=200)
def __str__(self):
return self.text
class QuestionAnswer(models.Model):
question = models.ForeignKey(MultiQuesModel, on_delete=models.CASCADE)
answer = models.ForeignKey(Answer, on_delete=models.CASCADE)
is_correct = models.BooleanField(default=False)
views.py(示例网站)
class AddMultiQuestionView(View):
def get(self, request):
if request.user.is_staff:
form = AddMultipleForm()
context = {"form": form}
return render(request, "multiformular.html", context)
else:
return redirect("index")
def post(self, request):
# if request.user.is_staff:
form = AddMultipleForm(request.POST)
print(request.POST)
print(form.is_valid())
print(form.errors)
if form.is_valid():
instance = form.save(commit=False)
instance.save()
answers_data = form.cleaned_data["answers"]
print(answers_data)
for answer_data in answers_data:
answer_text = answer_data["text"]
is_correct = answer_data["is_correct"]
answer, _ = Answer.objects.get_or_create(text=answer_text)
instance.answers.add(answer, through_defaults={"is_correct": is_correct})
return redirect("success_page")
else:
return render(request, "multiformular.html", {"form": form})
# else:
# return redirect("index")
2条答案
按热度按时间4smxwvx51#
现在我尝试为这个视图类AddMultiplayer View(View)添加Pytest:从这个问题。
conftest.py(示例网站)
test_views.py
代码
如果我手动测试它,它会工作,它会被写入数据库,我会被重定向:
zte4gxcn2#
主要问题可能是
ans_count
,除非指定,否则它总是使用1
,因此使用 one item。这意味着即使您发送了五个项目,清理仍然只会检索第一个。例如,我们可以将其设置为5,以获得前五个项目:当然,如果用户输入更多的项,这些项将无法解析。
您可以从数据中确定这些,使用:
话虽如此,您尝试做的是已经由
FormSet
[Django-doc]完成的大部分工作,因此您可能想看看它是否提供了一些支持,特别是因为验证多个小表单至少和单个表单一样麻烦。