From e035bfa35d9e3994f6ed6c7e7a09d9ae77164fc4 Mon Sep 17 00:00:00 2001 From: Sagun Devkota Date: Thu, 19 Sep 2024 13:12:30 +0545 Subject: [PATCH 1/2] fixed issue#68: Adding validation in choices. --- quiz/forms.py | 30 +++++++++++++++++++++++++++++ quiz/views.py | 10 ++++++---- templates/quiz/mcquestion_form.html | 2 +- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/quiz/forms.py b/quiz/forms.py index b3d3a11..4bbbced 100644 --- a/quiz/forms.py +++ b/quiz/forms.py @@ -59,11 +59,41 @@ class MCQuestionForm(forms.ModelForm): model = MCQuestion exclude = () +class MCQuestionFormSet(forms.BaseInlineFormSet): + def clean(self): + """ + Custom validation for the formset to ensure: + 1. At least two choices are provided and not marked for deletion. + 2. At least one of the choices is marked as correct. + """ + super().clean() + + # Collect non-deleted forms + valid_forms = [form for form in self.forms if not form.cleaned_data.get('DELETE', True)] + + valid_choices = ['choice' in form.cleaned_data.keys() for form in valid_forms] + if(not all(valid_choices)): + raise forms.ValidationError("You must add a valid choice name.") + + # If all forms are deleted, raise a validation error + if len(valid_forms) < 2: + raise forms.ValidationError("You must provide at least two choices.") + + # Check if at least one of the valid forms is marked as correct + correct_choices = [form.cleaned_data.get('correct', False) for form in valid_forms] + + if not any(correct_choices): + raise forms.ValidationError("One choice must be marked as correct.") + + if correct_choices.count(True)>1: + raise forms.ValidationError("Only one choice must be marked as correct.") + MCQuestionFormSet = inlineformset_factory( MCQuestion, Choice, form=MCQuestionForm, + formset=MCQuestionFormSet, fields=["choice", "correct"], can_delete=True, extra=5, diff --git a/quiz/views.py b/quiz/views.py index 0ea05bd..da1a678 100644 --- a/quiz/views.py +++ b/quiz/views.py @@ -118,10 +118,10 @@ class MCQuestionCreate(CreateView): context = self.get_context_data() formset = context["formset"] course = context["course"] - with transaction.atomic(): - form.instance.question = self.request.POST.get("content") - self.object = form.save() - if formset.is_valid(): + if formset.is_valid(): + with transaction.atomic(): + form.instance.question = self.request.POST.get("content") + self.object = form.save() formset.instance = self.object formset.save() if "another" in self.request.POST: @@ -131,6 +131,8 @@ class MCQuestionCreate(CreateView): quiz_id=self.kwargs["quiz_id"], ) return redirect("quiz_index", course.slug) + else: + return self.form_invalid(form) return super(MCQuestionCreate, self).form_invalid(form) diff --git a/templates/quiz/mcquestion_form.html b/templates/quiz/mcquestion_form.html index ae9f809..2d68194 100644 --- a/templates/quiz/mcquestion_form.html +++ b/templates/quiz/mcquestion_form.html @@ -16,7 +16,7 @@
Add questions [{{ quiz_obj|truncatechars:15 }}]


- +{{ formset.non_form_errors }}
{{ quizQuestions }} question added
From 28024874d643f1708ccc3f4ad3c34170b8386937 Mon Sep 17 00:00:00 2001 From: Adil Mohak Date: Sun, 29 Sep 2024 09:55:26 +0300 Subject: [PATCH 2/2] Quiz form validation and minor UI fixes --- templates/quiz/mcquestion_form.html | 19 ++++++++++++++----- templates/quiz/quiz_list.html | 5 +++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/templates/quiz/mcquestion_form.html b/templates/quiz/mcquestion_form.html index 2d68194..7cae6a7 100644 --- a/templates/quiz/mcquestion_form.html +++ b/templates/quiz/mcquestion_form.html @@ -14,9 +14,18 @@ -
Add questions [{{ quiz_obj|truncatechars:15 }}]
-

-{{ formset.non_form_errors }} +
Add questions [{{ quiz_obj|truncatechars:15 }}]
+ +{% if formset.non_form_errors %} +
+
    + {% for e in formset.non_form_errors %} +
  • {{ e }}
  • + {% endfor %} +
+
+{% endif %} +
{{ quizQuestions }} question added
@@ -40,11 +49,11 @@
- {{ fs.correct }} Correct + {{ fs.correct }} Correct
{{ fs.choice }}
- {{ fs.DELETE }} Delete + {{ fs.DELETE }} Delete
{% endfor %} diff --git a/templates/quiz/quiz_list.html b/templates/quiz/quiz_list.html index 283111b..326f337 100644 --- a/templates/quiz/quiz_list.html +++ b/templates/quiz/quiz_list.html @@ -72,6 +72,11 @@
+ + {% empty %} +

+ Course quizzes will appear here. +

{% endfor %}