Merge branch 'SagunDevkota-sagundevkota/issue#68'
This commit is contained in:
commit
d45b07a944
@ -59,11 +59,41 @@ class MCQuestionForm(forms.ModelForm):
|
|||||||
model = MCQuestion
|
model = MCQuestion
|
||||||
exclude = ()
|
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(
|
MCQuestionFormSet = inlineformset_factory(
|
||||||
MCQuestion,
|
MCQuestion,
|
||||||
Choice,
|
Choice,
|
||||||
form=MCQuestionForm,
|
form=MCQuestionForm,
|
||||||
|
formset=MCQuestionFormSet,
|
||||||
fields=["choice", "correct"],
|
fields=["choice", "correct"],
|
||||||
can_delete=True,
|
can_delete=True,
|
||||||
extra=5,
|
extra=5,
|
||||||
|
|||||||
@ -118,10 +118,10 @@ class MCQuestionCreate(CreateView):
|
|||||||
context = self.get_context_data()
|
context = self.get_context_data()
|
||||||
formset = context["formset"]
|
formset = context["formset"]
|
||||||
course = context["course"]
|
course = context["course"]
|
||||||
with transaction.atomic():
|
if formset.is_valid():
|
||||||
form.instance.question = self.request.POST.get("content")
|
with transaction.atomic():
|
||||||
self.object = form.save()
|
form.instance.question = self.request.POST.get("content")
|
||||||
if formset.is_valid():
|
self.object = form.save()
|
||||||
formset.instance = self.object
|
formset.instance = self.object
|
||||||
formset.save()
|
formset.save()
|
||||||
if "another" in self.request.POST:
|
if "another" in self.request.POST:
|
||||||
@ -131,6 +131,8 @@ class MCQuestionCreate(CreateView):
|
|||||||
quiz_id=self.kwargs["quiz_id"],
|
quiz_id=self.kwargs["quiz_id"],
|
||||||
)
|
)
|
||||||
return redirect("quiz_index", course.slug)
|
return redirect("quiz_index", course.slug)
|
||||||
|
else:
|
||||||
|
return self.form_invalid(form)
|
||||||
return super(MCQuestionCreate, self).form_invalid(form)
|
return super(MCQuestionCreate, self).form_invalid(form)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -14,8 +14,17 @@
|
|||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div class="title-1">Add questions [{{ quiz_obj|truncatechars:15 }}]</div>
|
<div class="title-1 mb-3">Add questions [{{ quiz_obj|truncatechars:15 }}]</div>
|
||||||
<br><br>
|
|
||||||
|
{% if formset.non_form_errors %}
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
<ul class="mb-0">
|
||||||
|
{% for e in formset.non_form_errors %}
|
||||||
|
<li>{{ e }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="info-text bg-orange mb-3">{{ quizQuestions }} question added</div>
|
<div class="info-text bg-orange mb-3">{{ quizQuestions }} question added</div>
|
||||||
@ -40,11 +49,11 @@
|
|||||||
<label for="username">{{ fs.label }}</label>
|
<label for="username">{{ fs.label }}</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text">{{ fs.correct }} <small class="ml-1">Correct</small></span>
|
<span class="input-group-text">{{ fs.correct }} <small class="ms-1">Correct</small></span>
|
||||||
</div>
|
</div>
|
||||||
{{ fs.choice }}
|
{{ fs.choice }}
|
||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text">{{ fs.DELETE }} <small class="ml-1">Delete</small></span>
|
<span class="input-group-text">{{ fs.DELETE }} <small class="ms-1">Delete</small></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@ -72,6 +72,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{% empty %}
|
||||||
|
<h4 class="text-center mt-5 py-5 text-muted">
|
||||||
|
<i class="fa-regular fa-folder-open me-2"></i> Course quizzes will appear here.
|
||||||
|
</h4>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user