from django.shortcuts import render, redirect, get_object_or_404 from django.contrib.auth.decorators import login_required from django.contrib.auth.models import User from django.urls import reverse from django.contrib import messages from .models import QivipQuiz, QivipQuestion from .forms import QuizForm, QuestionForm import json # Übersicht aller Quizze @login_required def overview_quiz(request): quizzes = QivipQuiz.objects.filter(user_id=request.user) return render(request, 'library/overview_quiz.html', {'quizzes': quizzes}) # Neues Quiz erstellen @login_required def new_quiz(request): if request.method == 'POST': form = QuizForm(request.POST) if form.is_valid(): quiz = form.save(commit=False) quiz.user_id = request.user quiz.save() form.save_m2m() # Speichert die Many-to-Many Beziehungen (Tags) return redirect('library:edit_quiz', pk=quiz.pk) else: form = QuizForm() return render(request, 'library/form.html', {'form': form}) # Quiz bearbeiten @login_required def edit_quiz(request, pk): quiz = get_object_or_404(QivipQuiz, pk=pk, user_id=request.user) if request.method == 'POST': form = QuizForm(request.POST, instance=quiz) if form.is_valid(): form.save() return redirect('library:overview_quiz') else: form = QuizForm(instance=quiz) return render(request, 'library/form.html', {'form': form}) # Quiz löschen @login_required def delete_quiz(request, pk): quiz = get_object_or_404(QivipQuiz, pk=pk, user_id=request.user) if request.method == 'POST': quiz.delete() return redirect('library:overview_quiz') return render(request, 'library/delete_confirmation.html', {'object': quiz}) # Quiz anzeigen @login_required def detail_quiz(request, pk): quiz = get_object_or_404(QivipQuiz, pk=pk, user_id=request.user) questions = QivipQuestion.objects.filter(quiz_id=quiz) # Parse JSON data for each question for question in questions: if question.data: question.data = json.loads(question.data) context = { 'quiz': quiz, 'questions': questions } return render(request, 'library/detail_quiz.html', context) # Übersicht aller Fragen @login_required def question_list(request): questions = QivipQuestion.objects.filter(quiz_id__user_id=request.user) # Parse JSON data for each question for question in questions: if question.data: question.data = json.loads(question.data) return render(request, 'library/question_list.html', {'questions': questions}) # Neue Frage erstellen @login_required def new_question(request): question_type = request.GET.get('type') quiz_id = request.GET.get('quiz_id') if not quiz_id: messages.error(request, 'Quiz ID muss angegeben werden.') return redirect('library:overview_quiz') try: quiz = QivipQuiz.objects.get(pk=quiz_id, user_id=request.user) except QivipQuiz.DoesNotExist: messages.error(request, 'Quiz nicht gefunden oder keine Berechtigung.') return redirect('library:overview_quiz') if question_type not in ['multiple_choice', 'true_false']: base_url = reverse('library:new_question') return redirect(f'{base_url}?type=multiple_choice&quiz_id={quiz_id}') if request.method == 'POST': question_text = request.POST.get('question', '') # Handle different question types if question_type == 'true_false': correct_answer = request.POST.get('correct_answer') == 'true' json_data = { 'type': question_type, 'question': question_text, 'options': [ {'value': 'Wahr', 'is_correct': correct_answer}, {'value': 'Falsch', 'is_correct': not correct_answer} ] } elif question_type == 'multiple_choice': options = [] i = 1 # Limit to maximum 6 options while request.POST.get(f'option_{i}') and i <= 6: is_correct = request.POST.get(f'correct_{i}') == '1' options.append({ 'order': i, 'value': request.POST.get(f'option_{i}'), 'is_correct': is_correct }) i += 1 # Validate minimum 2 options if len(options) < 2: messages.error(request, 'Mindestens zwei Optionen müssen angegeben werden.') return redirect(request.get_full_path()) json_data = { 'type': question_type, 'question': question_text, 'options': options } question = QivipQuestion() question.data = json.dumps(json_data) question.quiz_id = quiz question.save() return redirect('library:detail_quiz', pk=quiz.pk) else: # Initialize empty question data for new questions if question_type == 'true_false': question_data = { 'type': question_type, 'question': '', 'options': [ {'value': 'Wahr', 'is_correct': True}, {'value': 'Falsch', 'is_correct': False} ] } elif question_type == 'multiple_choice': question_data = { 'type': question_type, 'question': '', 'options': [ {'value': '', 'is_correct': False}, {'value': '', 'is_correct': False} ] } template_name = f'library/question/question_{question_type}.html' context = { 'question': question_data, 'quiz_id': quiz_id, 'quiz': quiz } return render(request, template_name, context) # Frage bearbeiten @login_required def edit_question(request, pk): question = get_object_or_404(QivipQuestion, pk=pk, quiz_id__user_id=request.user) if question.quiz_id.user_id != request.user: return redirect('library:question_list') # Parse the existing JSON data try: question_data = json.loads(question.data) if question.data else {} question_type = question_data.get('type', 'multiple_choice') # For true/false questions, get the correct answer from the options if question_type == 'true_false': # Default to true if no options exist correct_answer = True if question_data.get('options'): correct_answer = question_data['options'][0].get('is_correct', True) question_data = { 'type': question_type, 'question': question_data.get('question', ''), 'correct_answer': correct_answer, # Add this for template compatibility 'options': [ {'value': 'Wahr', 'is_correct': correct_answer}, {'value': 'Falsch', 'is_correct': not correct_answer} ] } else: # For multiple choice questions question_data.setdefault('type', question_type) question_data.setdefault('question', '') question_data.setdefault('options', []) except (json.JSONDecodeError, AttributeError): # Handle invalid JSON or None data question_type = question_data.get('type', 'multiple_choice') if question_type == 'true_false': question_data = { 'type': question_type, 'question': '', 'correct_answer': True, # Default to true for new questions 'options': [ {'value': 'Wahr', 'is_correct': True}, {'value': 'Falsch', 'is_correct': False} ] } else: question_data = { 'type': question_type, 'question': '', 'options': [] } if request.method == 'POST': question_text = request.POST.get('question', '') # Handle different question types if question_type == 'true_false': correct_answer = request.POST.get('correct_answer') == 'true' json_data = { 'type': question_type, 'question': question_text, 'options': [ {'value': 'Wahr', 'is_correct': correct_answer}, {'value': 'Falsch', 'is_correct': not correct_answer} ] } elif question_type == 'multiple_choice': options = [] i = 1 # Limit to maximum 6 options while request.POST.get(f'option_{i}') and i <= 6: options.append({ 'order': i, 'value': request.POST.get(f'option_{i}'), 'is_correct': request.POST.get(f'correct_{i}') == '1' }) i += 1 # Validate minimum 2 options if len(options) < 2: messages.error(request, 'Mindestens zwei Optionen müssen angegeben werden.') return redirect(request.get_full_path()) # Validate maximum 6 options if len(options) > 6: messages.error(request, 'Maximal 6 Optionen sind erlaubt.') return redirect(request.get_full_path()) json_data = { 'type': question_type, 'question': question_text, 'options': options } question.data = json.dumps(json_data) question.save() return redirect('library:detail_quiz', pk=question.quiz_id.pk) else: template_name = f'library/question/question_{question_type}.html' context = { 'question': {'data': question_data}, # Wrap in data structure expected by template 'quiz_id': question.quiz_id.pk, 'quiz': question.quiz_id } return render(request, template_name, context) # Frage löschen @login_required def delete_question(request, pk): question = get_object_or_404(QivipQuestion, pk=pk, quiz_id__user_id=request.user) # Parse JSON data for question if question.data: question.data = json.loads(question.data) if request.method == 'POST': question.delete() return redirect('library:detail_quiz', pk=question.quiz_id.pk) return render(request, 'library/delete_confirmation.html', {'object': question})