Merge branch '154-anzahl-wie-oft-ein-quiz-gespielt-worden-ist' into 'master'

Resolve "Anzahl, wie oft ein Quiz gespielt worden ist."

Closes #154

See merge request enrichment-2024/qivip!111
This commit is contained in:
ben8
2025-11-14 16:25:26 +00:00
12 changed files with 215 additions and 7 deletions

View File

@@ -0,0 +1,33 @@
# Generated by Django 5.1.7 on 2025-11-14 14:51
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('library', '0057_quizcategory_color'),
]
operations = [
migrations.AddField(
model_name='qivipquiz',
name='quiz_played_Lernmodus',
field=models.IntegerField(blank=True, default=0, null=True),
),
migrations.AddField(
model_name='qivipquiz',
name='quiz_played_Moderiermodus',
field=models.IntegerField(blank=True, default=0, null=True),
),
migrations.AddField(
model_name='qivipquiz',
name='quiz_played_Moderiermodus_players',
field=models.IntegerField(blank=True, default=0, null=True),
),
migrations.AddField(
model_name='qivipquiz',
name='single_player_or_multiple',
field=models.CharField(blank=True, max_length=20),
),
]

View File

@@ -0,0 +1,17 @@
# Generated by Django 5.1.7 on 2025-11-14 15:04
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('library', '0058_qivipquiz_quiz_played_lernmodus_and_more'),
]
operations = [
migrations.RemoveField(
model_name='qivipquiz',
name='single_player_or_multiple',
),
]

View File

@@ -45,6 +45,10 @@ class QivipQuiz(models.Model):
) )
quiz_played_Lernmodus = models.IntegerField(null=True, blank=True, default=0)
quiz_played_Moderiermodus= models.IntegerField(null=True, blank=True, default=0)
quiz_played_Moderiermodus_players= models.IntegerField(null=True, blank=True, default=0)
uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True) uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
user_id = models.ForeignKey(User, on_delete=models.CASCADE, related_name='quiz') 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') #creator = models.ForeignKey(User, on_delete=models.SET_NULL,blank=True, null=True, related_name='creator_quiz')

View File

@@ -811,6 +811,9 @@ def copy_quiz(request, pk):
new_quiz.base_quiz_id = pk new_quiz.base_quiz_id = pk
new_quiz.rating_count = 0 new_quiz.rating_count = 0
new_quiz.average_rating = 3.0 new_quiz.average_rating = 3.0
new_quiz.quiz_played_Lernmodus = 0
new_quiz.quiz_played_Moderiermodus = 0
new_quiz.quiz_played_Moderiermodus_players = 0
if original_quiz.status=="öffentlich": if original_quiz.status=="öffentlich":
new_quiz.published_at = timezone.now() new_quiz.published_at = timezone.now()
else: else:

View File

@@ -4,7 +4,7 @@ from channels.generic.websocket import AsyncWebsocketConsumer
from channels.db import database_sync_to_async from channels.db import database_sync_to_async
from django.utils import timezone from django.utils import timezone
from django.urls import reverse from django.urls import reverse
from play.models import QuizGame, QuizGameParticipant, QuizAnswer from play.models import QuizGame, QuizGameParticipant, QuizAnswer,QivipQuiz
from django.conf import settings from django.conf import settings
from geopy.distance import geodesic from geopy.distance import geodesic
@@ -149,6 +149,7 @@ class GameConsumer(AsyncWebsocketConsumer):
await self.show_scoreboard() await self.show_scoreboard()
elif message_type == 'finish_game': elif message_type == 'finish_game':
host_id = text_data_json['host_id'] host_id = text_data_json['host_id']
if await self.verify_host(host_id): if await self.verify_host(host_id):
await self.finish_game() await self.finish_game()
@@ -626,10 +627,34 @@ class GameConsumer(AsyncWebsocketConsumer):
} }
) )
@database_sync_to_async
def counter_played_quizzes(self): # Zähler, wie oft ein Quiz gespielt worden ist.
quiz = QuizGame.objects.get(join_code=self.join_code).quiz_id
quiz_game = QuizGame.objects.get(join_code=self.join_code)
if quiz_game.single_player_or_multiple=="multiple":
quiz.quiz_played_Moderiermodus+=1
active_participants = QuizGameParticipant.objects.filter(
quiz_game=quiz_game
).count()
quiz.quiz_played_Moderiermodus_players+=active_participants
else:
quiz.quiz_played_Lernmodus+=1
quiz.save()
@database_sync_to_async @database_sync_to_async
def _finish_game(self): def _finish_game(self):
try: try:
quiz_game = QuizGame.objects.get(join_code=self.join_code) quiz_game = QuizGame.objects.get(join_code=self.join_code)
quiz_game.current_state = 'finished' quiz_game.current_state = 'finished'
quiz_game.save() quiz_game.save()
return True return True
@@ -638,6 +663,7 @@ class GameConsumer(AsyncWebsocketConsumer):
async def finish_game(self): async def finish_game(self):
success = await self._finish_game() success = await self._finish_game()
await self.counter_played_quizzes()
if success: if success:
# Notify clients to redirect to finished page # Notify clients to redirect to finished page
await self.channel_layer.group_send( await self.channel_layer.group_send(

View File

@@ -0,0 +1,28 @@
# Generated by Django 5.1.7 on 2025-11-14 13:53
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('play', '0016_quizgameparticipant_coordinate_answer'),
]
operations = [
migrations.AddField(
model_name='quizgame',
name='quiz_played_Lernmodus',
field=models.IntegerField(blank=True, default=0, null=True),
),
migrations.AddField(
model_name='quizgame',
name='quiz_played_Moderiermodus',
field=models.IntegerField(blank=True, default=0, null=True),
),
migrations.AddField(
model_name='quizgame',
name='quiz_played_Moderiermodus_players',
field=models.IntegerField(blank=True, default=0, null=True),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.1.7 on 2025-11-14 14:11
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('play', '0017_quizgame_quiz_played_lernmodus_and_more'),
]
operations = [
migrations.AddField(
model_name='quizgame',
name='single_player_or_multiple',
field=models.CharField(blank=True, max_length=20),
),
]

View File

@@ -0,0 +1,29 @@
# Generated by Django 5.1.7 on 2025-11-14 14:50
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('play', '0018_quizgame_single_player_or_multiple'),
]
operations = [
migrations.RemoveField(
model_name='quizgame',
name='quiz_played_Lernmodus',
),
migrations.RemoveField(
model_name='quizgame',
name='quiz_played_Moderiermodus',
),
migrations.RemoveField(
model_name='quizgame',
name='quiz_played_Moderiermodus_players',
),
migrations.RemoveField(
model_name='quizgame',
name='single_player_or_multiple',
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.1.7 on 2025-11-14 15:04
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('play', '0019_remove_quizgame_quiz_played_lernmodus_and_more'),
]
operations = [
migrations.AddField(
model_name='quizgame',
name='single_player_or_multiple',
field=models.CharField(blank=True, max_length=20),
),
]

View File

@@ -15,7 +15,7 @@ class QuizGame(models.Model):
('scoreboard', 'Scoreboard'), ('scoreboard', 'Scoreboard'),
] ]
single_player_or_multiple=models.CharField(max_length=20, blank=True)
host_id = models.CharField(max_length=200, unique=True) host_id = models.CharField(max_length=200, unique=True)
join_code = models.CharField(max_length=6, unique=True, blank=True) join_code = models.CharField(max_length=6, unique=True, blank=True)
quiz_id = models.ForeignKey(QivipQuiz, on_delete=models.CASCADE) quiz_id = models.ForeignKey(QivipQuiz, on_delete=models.CASCADE)

View File

@@ -420,10 +420,20 @@ def waiting_room(request, join_code):
def selected_mode(request, join_code): def selected_mode(request, join_code):
mode = request.GET.get('mode','default') mode = request.GET.get('mode','default')
request.session['mode'] = mode request.session['mode'] = mode
quiz_game = QuizGame.objects.get(join_code=join_code)
if mode=="learn":
quiz_game.single_player_or_multiple="single"
else:
quiz_game.single_player_or_multiple="multiple"
quiz_game.save()
quiz_game = get_object_or_404(QuizGame, join_code=join_code) quiz_game = get_object_or_404(QuizGame, join_code=join_code)
quiz = get_object_or_404(QivipQuiz, pk=quiz_game.quiz_id.id) quiz = get_object_or_404(QivipQuiz, pk=quiz_game.quiz_id.id)
QuizGameParticipant.objects.filter(quiz_game=quiz_game).delete() QuizGameParticipant.objects.filter(quiz_game=quiz_game).delete()

View File

@@ -31,7 +31,7 @@
<path stroke-linecap="round" stroke-linejoin="round" <path stroke-linecap="round" stroke-linejoin="round"
d="M11.35 3.836c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75 2.25 2.25 0 0 0-.1-.664m-5.8 0A2.251 2.251 0 0 1 13.5 2.25H15c1.012 0 1.867.668 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m8.9-4.414c.376.023.75.05 1.124.08 1.131.094 1.976 1.057 1.976 2.192V16.5A2.25 2.25 0 0 1 18 18.75h-2.25m-7.5-10.5H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V18.75m-7.5-10.5h6.375c.621 0 1.125.504 1.125 1.125v9.375m-8.25-3 1.5 1.5 3-3.75" /> d="M11.35 3.836c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75 2.25 2.25 0 0 0-.1-.664m-5.8 0A2.251 2.251 0 0 1 13.5 2.25H15c1.012 0 1.867.668 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m8.9-4.414c.376.023.75.05 1.124.08 1.131.094 1.976 1.057 1.976 2.192V16.5A2.25 2.25 0 0 1 18 18.75h-2.25m-7.5-10.5H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V18.75m-7.5-10.5h6.375c.621 0 1.125.504 1.125 1.125v9.375m-8.25-3 1.5 1.5 3-3.75" />
</svg> </svg>
Quiz kopieren Quiz duplizieren
</a> </a>
{% if quiz.questions.count != 0 %} {% if quiz.questions.count != 0 %}
@@ -405,6 +405,28 @@
</ul> </ul>
</div> </div>
<div class="max-w-full p-4 mt-8 rounded-2xl bg-gray-100 dark:bg-transparent shadow-sm">
<p class="text-lg font-bold text-gray-800 dark:text-white dark:bg-transparent mb-3">
Quiz-Statistik
</p>
<div class="space-y-2 text-gray-700 dark:text-white ">
<p>
<span class="font-semibold">{{ quiz.quiz_played_Lernmodus }}</span>
mal im Lernmodus gespielt
</p>
<p>
<span class="font-semibold">{{ quiz.quiz_played_Moderiermodus }}</span>
mal im Moderiermodus gespielt
<span class="text-sm text-gray-500 dark:text-gray-400">
(insg. {{ quiz.quiz_played_Moderiermodus_players }} Spieler)
</span>
</p>
</div>
</div>
</div> </div>
{% endblock %} {% endblock %}