diff --git a/django/library/admin.py b/django/library/admin.py index 6526f60..7d617a5 100644 --- a/django/library/admin.py +++ b/django/library/admin.py @@ -1,5 +1,5 @@ from django.contrib import admin -from .models import QivipQuiz, QivipQuestion, QuizCategory, Tag +from .models import QivipQuiz, QivipQuestion, QivipQuizFavorite, QuizCategory # Für das QivipQuiz Modell class QivipQuizAdmin(admin.ModelAdmin): @@ -18,13 +18,13 @@ class QuizCategoryAdmin(admin.ModelAdmin): search_fields = ('name',) prepopulated_fields = {'slug': ('name',)} # Erstelle automatisch den Slug basierend auf dem Namen -# Für das Tag Modell -class TagAdmin(admin.ModelAdmin): - list_display = ('name',) # Zeige nur den Namen des Tags - search_fields = ('name',) + + +class QivipQuizFavoriteAdmin(admin.ModelAdmin): + list_display = ('user', 'favorite', 'quiz') # Welche Felder sollen in der Übersicht angezeigt werden # Registrierung der Modelle im Admin admin.site.register(QivipQuiz, QivipQuizAdmin) admin.site.register(QivipQuestion, QivipQuestionAdmin) admin.site.register(QuizCategory, QuizCategoryAdmin) -admin.site.register(Tag, TagAdmin) +admin.site.register(QivipQuizFavorite, QivipQuizFavoriteAdmin) diff --git a/django/library/forms.py b/django/library/forms.py index b0a75de..7cb8773 100644 --- a/django/library/forms.py +++ b/django/library/forms.py @@ -4,7 +4,7 @@ from .models import QivipQuiz, QivipQuestion class QuizForm(forms.ModelForm): class Meta: model = QivipQuiz - fields = ['name', 'description','image', 'status', 'category', 'tags','difficulty','credits'] + fields = ['name', 'description','image', 'status', 'category','difficulty','credits'] class QuestionForm(forms.ModelForm): class Meta: diff --git a/django/library/migrations/0033_remove_qivipquiz_tags_delete_tag.py b/django/library/migrations/0033_remove_qivipquiz_tags_delete_tag.py new file mode 100644 index 0000000..680c87a --- /dev/null +++ b/django/library/migrations/0033_remove_qivipquiz_tags_delete_tag.py @@ -0,0 +1,20 @@ +# Generated by Django 5.1.7 on 2025-04-10 13:59 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('library', '0032_qivipquiz_average_rating_qivipquiz_rating_count_and_more'), + ] + + operations = [ + migrations.RemoveField( + model_name='qivipquiz', + name='tags', + ), + migrations.DeleteModel( + name='Tag', + ), + ] diff --git a/django/library/migrations/0034_alter_qivipquiz_status.py b/django/library/migrations/0034_alter_qivipquiz_status.py new file mode 100644 index 0000000..27a3a46 --- /dev/null +++ b/django/library/migrations/0034_alter_qivipquiz_status.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.7 on 2025-04-10 14:04 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('library', '0033_remove_qivipquiz_tags_delete_tag'), + ] + + operations = [ + migrations.AlterField( + model_name='qivipquiz', + name='status', + field=models.CharField(choices=[('öffentlich', 'Öffentlich'), ('privat', 'Privat')], default='öffentlich', max_length=10), + ), + ] diff --git a/django/library/migrations/0035_qivipquiz_favorite.py b/django/library/migrations/0035_qivipquiz_favorite.py new file mode 100644 index 0000000..756b801 --- /dev/null +++ b/django/library/migrations/0035_qivipquiz_favorite.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.7 on 2025-04-10 14:52 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('library', '0034_alter_qivipquiz_status'), + ] + + operations = [ + migrations.AddField( + model_name='qivipquiz', + name='favorite', + field=models.BooleanField(default=False), + ), + ] diff --git a/django/library/migrations/0036_remove_qivipquiz_favorite_quizfavorite.py b/django/library/migrations/0036_remove_qivipquiz_favorite_quizfavorite.py new file mode 100644 index 0000000..f0efab0 --- /dev/null +++ b/django/library/migrations/0036_remove_qivipquiz_favorite_quizfavorite.py @@ -0,0 +1,32 @@ +# Generated by Django 5.1.7 on 2025-04-10 16:02 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('library', '0035_qivipquiz_favorite'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.RemoveField( + model_name='qivipquiz', + name='favorite', + ), + migrations.CreateModel( + name='QuizFavorite', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('favorite', models.BooleanField(default=False)), + ('quiz', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='library.qivipquiz')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'unique_together': {('user', 'quiz')}, + }, + ), + ] diff --git a/django/library/migrations/0037_rename_quizfavorite_qivipquizfavorite.py b/django/library/migrations/0037_rename_quizfavorite_qivipquizfavorite.py new file mode 100644 index 0000000..6eb61d5 --- /dev/null +++ b/django/library/migrations/0037_rename_quizfavorite_qivipquizfavorite.py @@ -0,0 +1,19 @@ +# Generated by Django 5.1.7 on 2025-04-10 16:05 + +from django.conf import settings +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('library', '0036_remove_qivipquiz_favorite_quizfavorite'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.RenameModel( + old_name='QuizFavorite', + new_name='QivipQuizFavorite', + ), + ] diff --git a/django/library/migrations/0038_alter_qivipquizfavorite_quiz.py b/django/library/migrations/0038_alter_qivipquizfavorite_quiz.py new file mode 100644 index 0000000..1efd121 --- /dev/null +++ b/django/library/migrations/0038_alter_qivipquizfavorite_quiz.py @@ -0,0 +1,19 @@ +# Generated by Django 5.1.7 on 2025-04-10 17:08 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('library', '0037_rename_quizfavorite_qivipquizfavorite'), + ] + + operations = [ + migrations.AlterField( + model_name='qivipquizfavorite', + name='quiz', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='favorites', to='library.qivipquiz'), + ), + ] 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/migrations/0045_remove_qivipquiz_favorite_date_and_more.py b/django/library/migrations/0045_remove_qivipquiz_favorite_date_and_more.py new file mode 100644 index 0000000..8d92ed4 --- /dev/null +++ b/django/library/migrations/0045_remove_qivipquiz_favorite_date_and_more.py @@ -0,0 +1,22 @@ +# Generated by Django 5.1.7 on 2025-04-11 16:34 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('library', '0044_remove_qivipquizfavorite_favorite_date_and_more'), + ] + + operations = [ + migrations.RemoveField( + model_name='qivipquiz', + name='favorite_date', + ), + migrations.AddField( + model_name='qivipquizfavorite', + name='favorite_date', + field=models.DateTimeField(auto_now=True), + ), + ] diff --git a/django/library/migrations/0046_alter_qivipquizfavorite_favorite_date.py b/django/library/migrations/0046_alter_qivipquizfavorite_favorite_date.py new file mode 100644 index 0000000..e08ca9d --- /dev/null +++ b/django/library/migrations/0046_alter_qivipquizfavorite_favorite_date.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.7 on 2025-04-11 16:50 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('library', '0045_remove_qivipquiz_favorite_date_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='qivipquizfavorite', + name='favorite_date', + field=models.DateTimeField(blank=True, null=True), + ), + ] diff --git a/django/library/models.py b/django/library/models.py index 8f0c8eb..8c1da34 100644 --- a/django/library/models.py +++ b/django/library/models.py @@ -7,7 +7,7 @@ from django.core.exceptions import ValidationError class QivipQuiz(models.Model): STATUS_VALUES = { "öffentlich": "Öffentlich", - "versteckt": "Versteckt", + #"versteckt": "Versteckt", "privat": "Privat", } DIFFICULTY_VALUES = { @@ -27,7 +27,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') @@ -35,11 +35,10 @@ 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) - tags = models.ManyToManyField('Tag', blank=True) - 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) @@ -47,6 +46,14 @@ class QivipQuiz(models.Model): return self.name +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 + favorite_date = models.DateTimeField(null=True, blank=True) + + class Meta: + unique_together = ('user', 'quiz') # Sicherstellen, dass es nur ein Favorit pro User und Quiz gibt # Create your models here. @@ -70,11 +77,7 @@ class QivipQuestion(models.Model): def __str__(self): return self.data[:50] -class Tag(models.Model): - name = models.CharField(max_length=100, unique=True) - def __str__(self): - return self.name class QuizRating(models.Model): quiz = models.ForeignKey(QivipQuiz, on_delete=models.CASCADE, related_name='ratings') diff --git a/django/library/urls.py b/django/library/urls.py index 28b2b76..1721a2b 100644 --- a/django/library/urls.py +++ b/django/library/urls.py @@ -15,5 +15,6 @@ urlpatterns = [ path('question/edit//', views.edit_question, name='edit_question'), path('question/delete//', views.delete_question, name='delete_question'), path('detail/copy//', views.copy_quiz, name='copy_quiz'), + path('favorite_quiz//', views.favorite_quiz, name='favorite_quiz'), ] diff --git a/django/library/views.py b/django/library/views.py index 83c209f..c770750 100644 --- a/django/library/views.py +++ b/django/library/views.py @@ -1,10 +1,12 @@ +from django.utils import timezone import uuid +from django.http import HttpResponse, HttpResponseRedirect 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 .models import QivipQuiz, QivipQuestion, QivipQuizFavorite from .forms import QuizForm, QuestionForm import json from django.core.paginator import Paginator @@ -17,12 +19,23 @@ from django.contrib.auth.models import User def overview_quiz(request): # Filter form = QuizFilterForm(request.GET) + try: + favorite_quizzes_data = QivipQuizFavorite.objects.filter(user=request.user, favorite=True).order_by("-favorite_date") + 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 = favorite_quizzes.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() @@ -30,11 +43,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) @@ -63,9 +114,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: @@ -80,17 +131,70 @@ def overview_quiz(request): except: other_quizzes = other_quizzes_paginator.page(1) + + + try: + favorite_quizzes = favorite_quizzes.filter( + favorites__user=request.user, # Filtere nach dem User + favorites__favorite=True # Filtere nach favorisierten Quizzes + ).order_by('-favorites__favorite_date') + except: + pass + + + # Pagination for favorite_quizzes + favorite_quizzes_paginator = Paginator(favorite_quizzes, 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, + 'favorite_quizzes':favorite_quizzes, 'my_quizzes': my_quizzes, 'other_quizzes': other_quizzes, 'form': form, } 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 + + + if favorite.favorite==True: + favorite.favorite_date = timezone.now() + + statement="Das Quiz '"+ favorite.quiz.name+ "' wurde erfolgreich zu den Favoriten hinzugefügt!" + messages.success(request,statement ) + else: + favorite.favorite_date = None + + statement="Das Quiz '"+ favorite.quiz.name+ "' wurde erfolgreich von den Favoriten entfernt!" + messages.error(request, statement) + + favorite.save() + else: + QivipQuizFavorite.objects.create(user=request.user, quiz=quiz, favorite=True, favorite_date=timezone.now()) + """ + referer = request.META.get('HTTP_REFERER') + if referer and 'library/' in referer: + + return redirect(request.META.get('HTTP_REFERER', 'library:overview_quiz')) + else: + return overview_quiz(request) + """ + return redirect(request.META.get('HTTP_REFERER', 'library:overview_quiz')) + # Neues Quiz erstellen @login_required @@ -102,7 +206,7 @@ def new_quiz(request): quiz.user_id = request.user #quiz.creator = request.user quiz.save() - form.save_m2m() # Speichert die Many-to-Many Beziehungen (Tags) + #form.save_m2m() # Speichert die Many-to-Many Beziehungen (Tags) return redirect('library:detail_quiz', pk=quiz.pk) else: diff --git a/django/play/urls.py b/django/play/urls.py index 81f59e8..df8326c 100644 --- a/django/play/urls.py +++ b/django/play/urls.py @@ -12,4 +12,5 @@ urlpatterns = [ path('game//waiting', views.waiting_room, name='waiting'), path('game//scores', views.scores, name='scores'), path('game//finished', views.finished, name='finished'), + path('select_mode/', views.select_mode, name='select_mode'), ] \ No newline at end of file diff --git a/django/play/views.py b/django/play/views.py index 82991d6..173bbeb 100644 --- a/django/play/views.py +++ b/django/play/views.py @@ -38,6 +38,11 @@ def lobby(request, join_code): context['participant'] = participant return render(request, 'play/lobby.html', context=context) +def select_mode(request,join_code): + return render(request, 'play/select_mode.html', {'join_code': join_code}) + + + def create_participant(request, join_code): quiz_game = get_object_or_404(QuizGame, join_code=join_code) @@ -85,7 +90,7 @@ def create_game(request, quiz_id): game.host_id = game.generate_unique_id() game.save() - response = HttpResponseRedirect(reverse('play:lobby', kwargs={'join_code': game.join_code})) + response = HttpResponseRedirect(reverse('play:select_mode', kwargs={'join_code': game.join_code})) response.set_cookie('host_id', game.host_id, max_age=3600) return response diff --git a/django/templates/base.html b/django/templates/base.html index 30c799e..416bfd7 100644 --- a/django/templates/base.html +++ b/django/templates/base.html @@ -66,6 +66,8 @@ }, duration); } }; + if (window.location.pathname !== "/library/") { + localStorage.setItem("meine_seite_scroll", 0);} {% block extra_js %}{% endblock %} diff --git a/django/templates/library/detail_quiz.html b/django/templates/library/detail_quiz.html index cecf631..17afbc8 100644 --- a/django/templates/library/detail_quiz.html +++ b/django/templates/library/detail_quiz.html @@ -3,29 +3,52 @@ {% block content %}
-
-

{{ quiz.name }}

-
+ +
+

{{ quiz.name }}

+ +
+ +
{% if quiz.user_id == request.user %} - + - + {% endif %} - - - - -   Quiz kopieren -
+ + +
+ +
{% if quiz.description %} @@ -62,18 +85,18 @@
-
+

Fragen

-
+
{% if quiz.user_id == request.user %} + class=" mt-1 bg-blue-100 text-blue-800 px-4 py-2 rounded-md text-xs lg:text-lg hover:border-blue-600 border-2"> Multiple Choice {% endif %} {% if quiz.user_id == request.user %} + class=" mt-1 bg-purple-100 text-purple-800 px-4 py-2 rounded-md text-xs lg:text-lg hover:border-blue-600 border-2"> Wahr/Falsch {% endif %} diff --git a/django/templates/library/overview_quiz.html b/django/templates/library/overview_quiz.html index 955cb27..4c27130 100644 --- a/django/templates/library/overview_quiz.html +++ b/django/templates/library/overview_quiz.html @@ -77,6 +77,7 @@
+ {% if user.is_authenticated %}
@@ -92,13 +93,42 @@
{% if quiz.image %} -
+
+ +
+
+
+ {% else %}
{% endif %} + {% if user.is_authenticated %} + {% if quiz.id not in favorite_quiz_ids %} +
+ + + + + + +
+ + {% else %} + + {% endif %} + {% endif %}
+ +
@@ -179,7 +209,7 @@ - {% if quiz.user == request.user %} + {% if quiz.user_id == request.user %} @@ -228,6 +258,198 @@
{% endif %} + + + +{% if user.is_authenticated %} +
+
+

Meine Favoriten

+
+
+
+ +
+
+ {% for quiz in favorite_quizzes %} +
+ + + + + + +
+ +

+ {{ quiz.name }} +

+ +

{{ quiz.description }}

+ + +
+ +
+ + + + {{ quiz.difficulty }} +
+ + +
+ + + + {{ quiz.questions.count }} Fragen +
+ + +
+ + + + {{ quiz.status }} +
+ + +
+ {% for i in '12345'|make_list %} + {% if forloop.counter <= quiz.average_rating|floatformat:0|add:0 %} + + {% else %} + + {% endif %} + {% endfor %} + ({{ quiz.rating_count }}) +
+
+ + + {% if quiz.authors.all %} +
+ + + + + {% for author in quiz.authors.all %} + {{ author.username }}{% if not forloop.last %}, {% endif %} + {% endfor %} + +
+ {% endif %} + + +
+ + + + + + Spielen + +
+ + + + + + + {% if quiz.user_id == request.user %} + + + + + + + + + + + {% endif %} +
+
+
+
+ {% endfor %} + +
+ + + {% if favorite_quizzes.paginator.num_pages > 1 %} +
+ {% if favorite_quizzes.has_previous %} + + + + + + {% endif %} + + Seite {{ favorite_quizzes.number }} von {{ favorite_quizzes.paginator.num_pages }} + + {% if my_quizzes.has_next %} + + + + + + {% endif %} +
+ {% endif %} +
+{% endif %} + + + + + + + + +
@@ -244,11 +466,39 @@
{% if quiz.image %} -
+
+ +
+
+
+ + {% else %}
{% endif %} + {% if user.is_authenticated %} + {% if quiz.id not in favorite_quiz_ids %} +
+ + + + + + +
+ + {% else %} + + {% endif %} + {% endif %}
@@ -374,5 +624,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 %} diff --git a/django/templates/partials/_nav.html b/django/templates/partials/_nav.html index 60f8a6f..963ebc8 100644 --- a/django/templates/partials/_nav.html +++ b/django/templates/partials/_nav.html @@ -1,23 +1,23 @@ -