diff --git a/django/library/migrations/0039_qivipquizfavorite_favorite_date.py b/django/library/migrations/0039_qivipquizfavorite_favorite_date.py new file mode 100644 index 0000000..a4eb4d8 --- /dev/null +++ b/django/library/migrations/0039_qivipquizfavorite_favorite_date.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.7 on 2025-04-11 12:40 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('library', '0038_alter_qivipquizfavorite_quiz'), + ] + + operations = [ + migrations.AddField( + model_name='qivipquizfavorite', + name='favorite_date', + field=models.DateTimeField(auto_now=True), + ), + ] diff --git a/django/library/migrations/0040_alter_qivipquiz_description.py b/django/library/migrations/0040_alter_qivipquiz_description.py new file mode 100644 index 0000000..16ac3b0 --- /dev/null +++ b/django/library/migrations/0040_alter_qivipquiz_description.py @@ -0,0 +1,19 @@ +# Generated by Django 5.1.7 on 2025-04-11 13:15 + +import library.models +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('library', '0039_qivipquizfavorite_favorite_date'), + ] + + operations = [ + migrations.AlterField( + model_name='qivipquiz', + name='description', + field=models.TextField(default='In dem Quiz geht es um ...', max_length=200, validators=[library.models.QivipQuiz.validate_description], verbose_name='Beschreibung'), + ), + ] diff --git a/django/library/migrations/0041_alter_qivipquiz_category_alter_qivipquiz_difficulty_and_more.py b/django/library/migrations/0041_alter_qivipquiz_category_alter_qivipquiz_difficulty_and_more.py new file mode 100644 index 0000000..32fee6b --- /dev/null +++ b/django/library/migrations/0041_alter_qivipquiz_category_alter_qivipquiz_difficulty_and_more.py @@ -0,0 +1,34 @@ +# Generated by Django 5.1.7 on 2025-04-11 13:21 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('library', '0040_alter_qivipquiz_description'), + ] + + operations = [ + migrations.AlterField( + model_name='qivipquiz', + name='category', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='quiz', to='library.quizcategory', verbose_name='Kategorie'), + ), + migrations.AlterField( + model_name='qivipquiz', + name='difficulty', + field=models.CharField(choices=[('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5'), ('nicht gesetzt', 'nicht gesetzt')], default='nicht gesetzt', help_text='1: niedrigste Schwierigkeit und 5: höchste Schwierigkeit', max_length=13, verbose_name='Schwierigkeit'), + ), + migrations.AlterField( + model_name='qivipquiz', + name='image', + field=models.ImageField(blank=True, max_length=256, null=True, upload_to='quiz_images/', verbose_name='Bild'), + ), + migrations.AlterField( + model_name='qivipquiz', + name='name', + field=models.CharField(max_length=75, verbose_name='Name des Quizzes'), + ), + ] diff --git a/django/library/migrations/0042_qivipquiz_favorite.py b/django/library/migrations/0042_qivipquiz_favorite.py new file mode 100644 index 0000000..9913a85 --- /dev/null +++ b/django/library/migrations/0042_qivipquiz_favorite.py @@ -0,0 +1,19 @@ +# Generated by Django 5.1.7 on 2025-04-11 13:43 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('library', '0041_alter_qivipquiz_category_alter_qivipquiz_difficulty_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='qivipquiz', + name='favorite', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='quizzes', to='library.qivipquizfavorite'), + ), + ] diff --git a/django/library/migrations/0043_remove_qivipquiz_favorite.py b/django/library/migrations/0043_remove_qivipquiz_favorite.py new file mode 100644 index 0000000..f7dfdfc --- /dev/null +++ b/django/library/migrations/0043_remove_qivipquiz_favorite.py @@ -0,0 +1,17 @@ +# Generated by Django 5.1.7 on 2025-04-11 15:25 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('library', '0042_qivipquiz_favorite'), + ] + + operations = [ + migrations.RemoveField( + model_name='qivipquiz', + name='favorite', + ), + ] diff --git a/django/library/migrations/0044_remove_qivipquizfavorite_favorite_date_and_more.py b/django/library/migrations/0044_remove_qivipquizfavorite_favorite_date_and_more.py new file mode 100644 index 0000000..c3df207 --- /dev/null +++ b/django/library/migrations/0044_remove_qivipquizfavorite_favorite_date_and_more.py @@ -0,0 +1,22 @@ +# Generated by Django 5.1.7 on 2025-04-11 16:03 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('library', '0043_remove_qivipquiz_favorite'), + ] + + operations = [ + migrations.RemoveField( + model_name='qivipquizfavorite', + name='favorite_date', + ), + migrations.AddField( + model_name='qivipquiz', + name='favorite_date', + field=models.DateTimeField(auto_now=True), + ), + ] diff --git a/django/library/models.py b/django/library/models.py index 2d63668..b1769b0 100644 --- a/django/library/models.py +++ b/django/library/models.py @@ -24,7 +24,7 @@ class QivipQuiz(models.Model): if value.strip() == "In dem Quiz geht es um ...": raise ValidationError("Bitte gib eine aussagekräftige Beschreibung ein.") - image = models.ImageField(max_length=256, upload_to='quiz_images/', blank=True, null=True) # Bild speichern in media/quiz_images/ + image = models.ImageField(max_length=256,verbose_name="Bild", upload_to='quiz_images/', blank=True, null=True) # Bild speichern in media/quiz_images/ uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True) user_id = models.ForeignKey(User, on_delete=models.CASCADE, related_name='quiz') #creator = models.ForeignKey(User, on_delete=models.SET_NULL,blank=True, null=True, related_name='creator_quiz') @@ -32,13 +32,14 @@ class QivipQuiz(models.Model): creation_date = models.DateTimeField(auto_now_add=True) update_date = models.DateTimeField(auto_now=True) status = models.CharField(max_length=10, choices=list(STATUS_VALUES.items()), default="öffentlich") - category = models.ForeignKey('QuizCategory', related_name='quiz', on_delete=models.CASCADE) - name = models.CharField(max_length=75) - description = models.TextField(validators=[validate_description],max_length=200,blank=False, default="In dem Quiz geht es um ...") - difficulty= models.CharField(max_length=13, choices=list(DIFFICULTY_VALUES.items()), default="nicht gesetzt", help_text="1: niedrigste Schwierigkeit und 5: höchste Schwierigkeit") + category = models.ForeignKey('QuizCategory',verbose_name="Kategorie", related_name='quiz', on_delete=models.CASCADE) + name = models.CharField(max_length=75,verbose_name="Name des Quizzes") + description = models.TextField(validators=[validate_description],max_length=200,blank=False, default="In dem Quiz geht es um ...", verbose_name="Beschreibung") + difficulty= models.CharField(verbose_name="Schwierigkeit", max_length=13, choices=list(DIFFICULTY_VALUES.items()), default="nicht gesetzt", help_text="1: niedrigste Schwierigkeit und 5: höchste Schwierigkeit") credits=models.TextField(blank=True, editable=True) average_rating = models.FloatField(default=3.0) rating_count = models.IntegerField(default=0) + favorite_date=models.DateTimeField(auto_now=True) def __str__(self): return self.name @@ -47,6 +48,7 @@ class QivipQuizFavorite(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) # Verknüpfung zu User quiz = models.ForeignKey(QivipQuiz, on_delete=models.CASCADE, related_name='favorites') # Verknüpfung zu Quiz favorite = models.BooleanField(default=False) # Favoritenstatus + class Meta: unique_together = ('user', 'quiz') # Sicherstellen, dass es nur ein Favorit pro User und Quiz gibt diff --git a/django/library/views.py b/django/library/views.py index 6b2a174..565709e 100644 --- a/django/library/views.py +++ b/django/library/views.py @@ -19,20 +19,22 @@ def overview_quiz(request): # Filter form = QuizFilterForm(request.GET) try: - favorite_quizzes = QivipQuizFavorite.objects.filter(user=request.user, favorite=True) - favorite_quiz_ids = favorite_quizzes.values_list('quiz', flat=True) + favorite_quizzes_data = QivipQuizFavorite.objects.filter(user=request.user, favorite=True) + favorite_quiz_ids = favorite_quizzes_data.values_list('quiz', flat=True) favorite_quizzes = QivipQuiz.objects.filter(id__in=favorite_quiz_ids) except: + favorite_quizzes_data = QivipQuizFavorite.objects.none() favorite_quizzes = QivipQuizFavorite.objects.none() favorite_quiz_ids = favorite_quizzes.none() favorite_quizzes = QivipQuiz.objects.none() - # Initialize querysets if request.user.is_authenticated: filter_my_quizzes = QivipQuiz.objects.filter(user_id=request.user).annotate(max_amout_questions=Count('questions')) + favorite_quizzes = QivipQuiz.objects.filter(id__in=favorite_quiz_ids).annotate(max_amout_questions=Count('questions')) filter_other_quizzes = QivipQuiz.objects.exclude(user_id=request.user) else: + favorite_quizzes = QivipQuiz.objects.none() filter_my_quizzes = QivipQuiz.objects.none() filter_other_quizzes = QivipQuiz.objects.all() @@ -40,11 +42,49 @@ def overview_quiz(request): filter_other_quizzes = filter_other_quizzes.annotate(max_amout_questions=Count('questions')) filter_other_quizzes = filter_other_quizzes.filter(max_amout_questions__gte=1, status='öffentlich') + + + + 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') + + filters = {} + if username: + try: + user = User.objects.get(username=username) + filters['user_id'] = user.id + except User.DoesNotExist: + favorite_quizzes = QivipQuiz.objects.none() + filter_my_quizzes = QivipQuiz.objects.none() + filter_other_quizzes=QivipQuiz.objects.none() + + if search: + filters['name__icontains'] = search + if min_amout_questions: + filters['max_amout_questions__gte'] = min_amout_questions + if max_amout_questions: + filters['max_amout_questions__lte'] = max_amout_questions + + try: + filter_other_quizzes = filter_other_quizzes.filter(**filters) + except: + filter_other_quizzes=QivipQuiz.objects.none() + try: + filter_my_quizzes = filter_my_quizzes.filter(**filters) + except: + filter_my_quizzes=QivipQuiz.objects.none() + + try: + favorite_quizzes = favorite_quizzes.filter(**filters) + except: + favorite_quizzes=QivipQuiz.objects.none() + + """ 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) @@ -73,9 +113,9 @@ def overview_quiz(request): filter_other_quizzes=filter_other_quizzes.exclude(user_id=request.user) except: filter_other_quizzes=filter_other_quizzes + """ - # Pagination for my quizzes my_quizzes_paginator = Paginator(filter_my_quizzes.order_by('-creation_date'), 8) # 8 quizzes per page try: @@ -90,6 +130,19 @@ def overview_quiz(request): except: other_quizzes = other_quizzes_paginator.page(1) + + + + + + + # Pagination for favorite_quizzes + favorite_quizzes_paginator = Paginator(favorite_quizzes.order_by("-favorite_date"), 8) # 8 quizzes per page + try: + favorite_quizzes = favorite_quizzes_paginator.page(request.GET.get('my_page', 1)) + except: + favorite_quizzes = favorite_quizzes_paginator.page(1) + context = { 'show_search': True, 'favorite_quiz_ids': favorite_quiz_ids, @@ -100,23 +153,32 @@ def overview_quiz(request): } return render(request, 'library/overview_quiz.html', context) - # Neues Quiz erstellen @login_required def favorite_quiz(request, pk): quiz= get_object_or_404(QivipQuiz, pk=pk) favorite = QivipQuizFavorite.objects.filter(user=request.user, quiz=quiz).first() + if favorite: favorite.favorite=not favorite.favorite - print(favorite.favorite) + favorite.save() + + if favorite.favorite==True: + quiz.save(update_fields=['favorite_date']) + statement="Das Quiz '"+ favorite.quiz.name+ "' wurde erfolgreich zu den Favoriten hinzugefügt!" + messages.success(request,statement ) + else: + statement="Das Quiz '"+ favorite.quiz.name+ "' wurde erfolgreich von den Favoriten entfernt!" + messages.error(request, statement) + else: QivipQuizFavorite.objects.create(user=request.user, quiz=quiz, favorite=True) - return redirect('library:overview_quiz') + return redirect(request.META.get('HTTP_REFERER', 'library:overview_quiz')) # Neues Quiz erstellen @login_required diff --git a/django/templates/library/overview_quiz.html b/django/templates/library/overview_quiz.html index a66677c..7a420cd 100644 --- a/django/templates/library/overview_quiz.html +++ b/django/templates/library/overview_quiz.html @@ -619,5 +619,20 @@ document.addEventListener('DOMContentLoaded', function() { document.getElementById('filterPanel').classList.toggle('show'); }); }); + +if (window.location.pathname === "/library/") { + window.addEventListener("beforeunload", function () { + localStorage.setItem("meine_seite_scroll", window.scrollY); + }); + + window.addEventListener("load", function () { + const scrollPos = localStorage.getItem("meine_seite_scroll"); + if (scrollPos !== null) { + window.scrollTo(0, parseInt(scrollPos)); + } + }); +} + + {% endblock content %}