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 from django.core.paginator import Paginator from .models import QivipQuiz from .forms import QuizFilterForm from django.db.models import Count from django.contrib.auth.models import User # Übersicht aller Quizze def overview_quiz(request): #Filter form = QuizFilterForm(request.GET) try: filter_my_quizzes = QivipQuiz.objects.filter(user_id=request.user).annotate(max_amout_questions=Count('question')) except: filter_my_quizzes = QivipQuiz.objects.none() filter_other_quizzes = QivipQuiz.objects.annotate(max_amout_questions=Count('question')) if form.is_valid(): search = form.cleaned_data.get('search') username= form.cleaned_data.get('user') max_amout_questions= form.cleaned_data.get('max_amout_questions') min_amout_questions= form.cleaned_data.get('min_amout_questions') if search: # Suche nach Namen filter_other_quizzes = filter_other_quizzes.filter(name__icontains=search) filter_my_quizzes = filter_my_quizzes.filter(name__icontains=search) if min_amout_questions: filter_other_quizzes = filter_other_quizzes.filter(max_amout_questions__gte=min_amout_questions) try: filter_my_quizzes =filter_my_quizzes.filter(max_amout_questions__gte=min_amout_questions) except: filter_my_quizzes = QivipQuiz.objects.none() if max_amout_questions: filter_other_quizzes = filter_other_quizzes.filter(max_amout_questions__lte=max_amout_questions) try: filter_my_quizzes =filter_my_quizzes.filter(max_amout_questions__lte=max_amout_questions) except: filter_my_quizzes = QivipQuiz.objects.none() if username: try: user = User.objects.get(username=username) # Benutzer anhand des Namens holen filter_other_quizzes = filter_other_quizzes.filter(user_id=user.id) filter_my_quizzes = filter_my_quizzes.filter(user_id=user.id) # Nach der user_id filtern except User.DoesNotExist: filter_other_quizzes = QivipQuiz.objects.none() # Falls User nicht existiert, leere Query zurückgeben filter_my_quizzes = QivipQuiz.objects.none() try: filter_other_quizzes=filter_other_quizzes.exclude(user_id=request.user) except: filter_other_quizzes=filter_other_quizzes # Anzahl der Quiz pro Seite für Swiper print("kein Filter ,form_valid") context = { 'show_search': True, 'filter_my_quizzes': filter_my_quizzes, 'filter_other_quizzes': filter_other_quizzes, 'form': form, } return render(request, 'library/overview_quiz.html', context) # Neues Quiz erstellen @login_required def new_quiz(request): if request.method == 'POST': form = QuizForm(request.POST, request.FILES) 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:detail_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, files=request.FILES) if form.is_valid(): form.save() return redirect('library:detail_quiz', pk=quiz.pk) 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})