1
0
Files
medical-notes/quiz/quiz/views.py
2025-12-22 03:19:48 +01:00

150 lines
4.7 KiB
Python

from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, redirect, get_object_or_404
from django.urls import reverse
from django.views.decorators.http import require_http_methods
from django.db.models import Q
from .models import Question, QuizResult, Tag
from .forms import CreateQuizForm
def handle_tag_filter(request):
tag_slug = request.GET.get('tag')
if tag_slug is not None:
if tag_slug == "":
if 'quiz_tag' in request.session:
del request.session['quiz_tag']
else:
request.session['quiz_tag'] = tag_slug
def create_quiz(request):
if request.method == 'POST':
form = CreateQuizForm(request.POST)
if form.is_valid():
# clear existing session data
keys_to_clear = ['quiz_filter_course_id', 'quiz_filter_tag_ids', 'quiz_filter_types', 'quiz_tag']
for key in keys_to_clear:
if key in request.session:
del request.session[key]
course = form.cleaned_data.get('course')
tags = form.cleaned_data.get('tags')
question_types = form.cleaned_data.get('question_type')
if course:
request.session['quiz_filter_course_id'] = course.id
if tags:
request.session['quiz_filter_tag_ids'] = list(tags.values_list('id', flat=True))
if question_types:
request.session['quiz_filter_types'] = question_types
return redirect('next_question')
else:
form = CreateQuizForm()
return render(request, 'quiz_create.html', {'form': form})
def index(request):
handle_tag_filter(request)
total_questions = Question.objects.count()
answered_count = QuizResult.objects.filter(user=request.quiz_user).count()
context = {
'total_questions': total_questions,
'answered_count': answered_count,
'tags': Tag.objects.all(),
'current_tag': request.session.get('quiz_tag'),
}
return render(request, 'index.html', context)
def get_next_question(request):
# Handle tag filtering
handle_tag_filter(request)
current_tag = request.session.get('quiz_tag')
# New filters
filter_course_id = request.session.get('quiz_filter_course_id')
filter_tag_ids = request.session.get('quiz_filter_tag_ids')
filter_types = request.session.get('quiz_filter_types')
answered_ids = QuizResult.objects.filter(user=request.quiz_user).values_list('question_id', flat=True)
questions = Question.objects.exclude(id__in=answered_ids)
# Apply filters
if current_tag:
questions = questions.filter(tags__slug=current_tag)
if filter_course_id:
questions = questions.filter(exam__course_id=filter_course_id)
if filter_tag_ids:
questions = questions.filter(tags__id__in=filter_tag_ids)
if filter_types:
# "single" -> no comma
# "multi" -> comma
q_objs = Q()
if 'single' in filter_types:
q_objs |= ~Q(correct_answer__contains=',')
if 'multi' in filter_types:
q_objs |= Q(correct_answer__contains=',')
if q_objs:
questions = questions.filter(q_objs)
# Distinguish questions based on filters to ensure we don't get duplicates if filtering by many-to-many
questions = questions.distinct()
next_question = questions.first()
if not next_question:
return render(request, 'partials/complete.html')
return render(request, 'partials/question.html', {'question': next_question})
@require_http_methods(["POST"])
def submit_answer(request):
question_id = request.POST.get('question_id')
selected_answer = request.POST.get('answer')
if not question_id or not selected_answer:
return HttpResponse("Invalid submission", status=400)
try:
question = Question.objects.get(id=question_id)
except Question.DoesNotExist:
return HttpResponse("Question not found", status=404)
is_correct = selected_answer == question.correct_answer
QuizResult.objects.update_or_create(
user=request.quiz_user,
question=question,
defaults={
'selected_answer': selected_answer,
'is_correct': is_correct,
}
)
return get_next_question(request)
def stats(request):
results = QuizResult.objects.filter(user=request.quiz_user)
total = results.count()
correct = results.filter(is_correct=True).count()
context = {
'total': total,
'correct': correct,
'percentage': round((correct / total * 100) if total > 0 else 0, 1),
}
return render(request, 'stats.html', context)