Bilder für Fragen

This commit is contained in:
Juhn-Vitus Saß
2025-04-18 21:26:40 +02:00
parent 73cd52ea3d
commit d824816be8
11 changed files with 92 additions and 6 deletions

View File

@@ -43,6 +43,7 @@ INSTALLED_APPS = [
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'channels', 'channels',
'django_cleanup',
] ]
MIDDLEWARE = [ MIDDLEWARE = [

View File

@@ -0,0 +1,14 @@
# Generated by Django 5.1.7 on 2025-04-18 11:34
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('library', '0035_alter_qivipquestion_time_per_question'),
('library', '0046_alter_qivipquizfavorite_favorite_date'),
]
operations = [
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.1.7 on 2025-04-18 11:34
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('library', '0047_merge_20250418_1334'),
]
operations = [
migrations.AddField(
model_name='qivipquestion',
name='image',
field=models.ImageField(blank=True, height_field=900, max_length=200, null=True, upload_to='question_images/', verbose_name='Bild', width_field=1000),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.1.7 on 2025-04-18 19:04
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('library', '0048_qivipquestion_image'),
]
operations = [
migrations.AlterField(
model_name='qivipquestion',
name='image',
field=models.ImageField(blank=True, null=True, upload_to='question_images/', verbose_name='Bild'),
),
]

View File

@@ -74,6 +74,7 @@ class QivipQuestion(models.Model):
update_date = models.DateTimeField(auto_now=True) update_date = models.DateTimeField(auto_now=True)
data = models.TextField() data = models.TextField()
time_per_question = models.CharField(max_length=3, choices=list(TIME_VALUES.items()), default=30, help_text="Zeit pro Frage in Sekunden") time_per_question = models.CharField(max_length=3, choices=list(TIME_VALUES.items()), default=30, help_text="Zeit pro Frage in Sekunden")
image = models.ImageField(verbose_name="Bild", upload_to="question_images/", blank=True, null=True)
def __str__(self): def __str__(self):
return self.data[:50] return self.data[:50]

View File

@@ -348,6 +348,7 @@ def new_question(request):
if request.method == 'POST': if request.method == 'POST':
question_text = request.POST.get('question', '') question_text = request.POST.get('question', '')
question_image = request.FILES['question_image']
# Handle different question types # Handle different question types
if question_type == 'true_false': if question_type == 'true_false':
@@ -387,6 +388,7 @@ def new_question(request):
question = QivipQuestion() question = QivipQuestion()
question.data = json.dumps(json_data) question.data = json.dumps(json_data)
question.quiz_id = quiz question.quiz_id = quiz
question.image = question_image
question.time_per_question = request.POST.get('time_per_question', '30') question.time_per_question = request.POST.get('time_per_question', '30')
question.save() question.save()
#return modified(request, pk=quiz.pk) #return modified(request, pk=quiz.pk)
@@ -435,6 +437,7 @@ def edit_question(request, pk):
try: try:
question_data = json.loads(question.data) if question.data else {} question_data = json.loads(question.data) if question.data else {}
question_type = question_data.get('type', 'multiple_choice') question_type = question_data.get('type', 'multiple_choice')
question_image = question.image
# For true/false questions, get the correct answer from the options # For true/false questions, get the correct answer from the options
if question_type == 'true_false': if question_type == 'true_false':
@@ -479,6 +482,10 @@ def edit_question(request, pk):
if request.method == 'POST': if request.method == 'POST':
question_text = request.POST.get('question', '') question_text = request.POST.get('question', '')
try:
question_image = request.FILES['question_image']
except Exception:
pass
# Handle different question types # Handle different question types
if question_type == 'true_false': if question_type == 'true_false':
@@ -521,6 +528,7 @@ def edit_question(request, pk):
question.data = json.dumps(json_data) question.data = json.dumps(json_data)
question.time_per_question = request.POST.get('time_per_question', '30') question.time_per_question = request.POST.get('time_per_question', '30')
question.image = question_image
question.save() question.save()
#return modified(request, question.quiz_id.pk) #return modified(request, question.quiz_id.pk)
return redirect('library:detail_quiz', pk=question.quiz_id.pk) return redirect('library:detail_quiz', pk=question.quiz_id.pk)
@@ -532,6 +540,7 @@ def edit_question(request, pk):
'quiz_id': question.quiz_id.pk, 'quiz_id': question.quiz_id.pk,
'quiz': question.quiz_id, 'quiz': question.quiz_id,
'time_per_question': question.time_per_question, 'time_per_question': question.time_per_question,
'image': question_image,
} }
return render(request, template_name, context) return render(request, template_name, context)

View File

@@ -219,7 +219,8 @@ def question(request, join_code):
'host_id': quiz_game.host_id, 'host_id': quiz_game.host_id,
'start_time': int(quiz_game.question_start_time.timestamp() * 1000), 'start_time': int(quiz_game.question_start_time.timestamp() * 1000),
'question_index': quiz_game.current_question_index, 'question_index': quiz_game.current_question_index,
'total_questions': len(questions) 'total_questions': len(questions),
'question_image': current_question.image
}) })
# Handle participant view # Handle participant view
@@ -239,7 +240,7 @@ def question(request, join_code):
'participant': participant, 'participant': participant,
'start_time': int(quiz_game.question_start_time.timestamp() * 1000), 'start_time': int(quiz_game.question_start_time.timestamp() * 1000),
'question_index': quiz_game.current_question_index, 'question_index': quiz_game.current_question_index,
'total_questions': len(questions) 'total_questions': len(questions),
}) })
def waiting_room(request, join_code): def waiting_room(request, join_code):

View File

@@ -10,7 +10,7 @@
</a> </a>
</div> </div>
<div class="bg-white rounded-lg shadow-md p-6 border-blue-600 border-2 rounded-xl shadow-md"> <div class="bg-white rounded-lg shadow-md p-6 border-blue-600 border-2 rounded-xl shadow-md">
<form method="post" class="space-y-6"> <form method="post" class="space-y-6" enctype="multipart/form-data">
{% csrf_token %} {% csrf_token %}
<!-- Question Text --> <!-- Question Text -->
@@ -23,6 +23,15 @@
</div> </div>
</div> </div>
{% if image %}
<img src="{{ image.url }}" style="max-width: 500px;" alt="Bild der Frage">
{% endif %}
<div>
<label class="font-bold" for="question_image">Bild:</label>
<input value="image.url" class="bg-blue-200 p-2 m-2 rounded-lg border-2 border-blue-400" type="file" name="question_image" id="question_image">
</div>
<!-- Options --> <!-- Options -->
<div> <div>
<label class="block text-sm font-medium text-gray-700 mb-2">Antwortmöglichkeiten</label> <label class="block text-sm font-medium text-gray-700 mb-2">Antwortmöglichkeiten</label>

View File

@@ -11,7 +11,7 @@
</div> </div>
<div class="bg-white rounded-lg shadow-md p-6 border-blue-600 border-2 rounded-xl shadow-md"> <div class="bg-white rounded-lg shadow-md p-6 border-blue-600 border-2 rounded-xl shadow-md">
<form method="post" class="space-y-6"> <form method="post" class="space-y-6" enctype="multipart/form-data">
{% csrf_token %} {% csrf_token %}
<!-- Question Text --> <!-- Question Text -->
@@ -24,6 +24,14 @@
</div> </div>
</div> </div>
{% if image %}
<img src="{{ image.url }}" style="max-width: 500px;" alt="Bild der Frage">
{% endif %}
<div>
<label class="font-bold" for="question_image">Bild:</label>
<input class="bg-blue-200 p-2 m-2 rounded-lg border-2 border-blue-400" type="file" name="question_image" id="question_image">
</div>
<!-- True/False Selection --> <!-- True/False Selection -->
<div> <div>
<label class="block text-sm font-medium text-gray-700 mb-2">Richtige Antwort</label> <label class="block text-sm font-medium text-gray-700 mb-2">Richtige Antwort</label>

View File

@@ -6,6 +6,12 @@
<p class="text-gray-700 font-bold text-xl mb-4">Frage {{ question_index|add:1 }} von {{ total_questions }}</p> <p class="text-gray-700 font-bold text-xl mb-4">Frage {{ question_index|add:1 }} von {{ total_questions }}</p>
<h1 class="text-3xl font-bold mb-6">{{ question_data.question }}</h1> <h1 class="text-3xl font-bold mb-6">{{ question_data.question }}</h1>
{% if question_image %}
<div class="flex justify-center">
<img class="m-4" src="{{ question_image.url }}" style="max-width: 500px;" alt="Bild der Frage">
</div>
{% endif %}
<div class="grid grid-cols-2 gap-4 mb-6"> <div class="grid grid-cols-2 gap-4 mb-6">
<div class="p-4 bg-blue-50 rounded-lg"> <div class="p-4 bg-blue-50 rounded-lg">
<p class="text-blue-600 text-xl mb-2">Verbleibende Zeit</p> <p class="text-blue-600 text-xl mb-2">Verbleibende Zeit</p>

View File

@@ -4,3 +4,4 @@ channels~=4.2.0 # WebSocket support
daphne~=4.1.2 # ASGI server daphne~=4.1.2 # ASGI server
pillow~=11.1.0 # Image handling pillow~=11.1.0 # Image handling
whitenoise~=6.6.0 # Static file serving whitenoise~=6.6.0 # Static file serving
django-cleanup