Resolve "Bilder für Fragen und co." #216

Merged
jvs merged 2 commits from 23-bilder-fur-fragen-und-co into master 2025-04-18 19:30:16 +00:00
11 changed files with 96 additions and 9 deletions

View File

@@ -43,6 +43,7 @@ INSTALLED_APPS = [
'django.contrib.messages',
'django.contrib.staticfiles',
'channels',
'django_cleanup',
]
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)
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")
image = models.ImageField(verbose_name="Bild", upload_to="question_images/", blank=True, null=True)
def __str__(self):
return self.data[:50]

View File

@@ -316,6 +316,7 @@ def new_question(request):
if request.method == 'POST':
question_text = request.POST.get('question', '')
question_image = request.FILES['question_image']
# Handle different question types
if question_type == 'true_false':
@@ -355,6 +356,7 @@ def new_question(request):
question = QivipQuestion()
question.data = json.dumps(json_data)
question.quiz_id = quiz
question.image = question_image
question.time_per_question = request.POST.get('time_per_question', '30')
question.save()
#return modified(request, pk=quiz.pk)
@@ -403,6 +405,7 @@ def edit_question(request, pk):
try:
question_data = json.loads(question.data) if question.data else {}
question_type = question_data.get('type', 'multiple_choice')
question_image = question.image
# For true/false questions, get the correct answer from the options
if question_type == 'true_false':
@@ -447,6 +450,10 @@ def edit_question(request, pk):
if request.method == 'POST':
question_text = request.POST.get('question', '')
try:
question_image = request.FILES['question_image']
except Exception:
pass
# Handle different question types
if question_type == 'true_false':
@@ -489,6 +496,7 @@ def edit_question(request, pk):
question.data = json.dumps(json_data)
question.time_per_question = request.POST.get('time_per_question', '30')
question.image = question_image
question.save()
#return modified(request, question.quiz_id.pk)
return redirect('library:detail_quiz', pk=question.quiz_id.pk)
@@ -500,6 +508,7 @@ def edit_question(request, pk):
'quiz_id': question.quiz_id.pk,
'quiz': question.quiz_id,
'time_per_question': question.time_per_question,
'image': question_image,
}
return render(request, template_name, context)

View File

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

View File

@@ -10,7 +10,7 @@
</a>
</div>
<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 %}
<!-- Question Text -->
@@ -23,6 +23,15 @@
</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 -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Antwortmöglichkeiten</label>

View File

@@ -11,7 +11,7 @@
</div>
<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 %}
<!-- Question Text -->
@@ -24,6 +24,14 @@
</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 -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Richtige Antwort</label>

View File

@@ -12,11 +12,18 @@
<div class="bg-white rounded-lg shadow-md p-6 mb-6">
<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>
{% 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 %}
{% if request.session.mode == "learn" %}
<div class="grid grid-cols-1 gap-4 mb-6">
{% else %}
<div class="grid grid-cols-2 gap-4 mb-6">
{% endif %}
{% else %}
<div class="grid grid-cols-2 gap-4 mb-6">
{% endif %}
{% if request.session.mode != "learn" %}
<div class="p-4 bg-blue-50 rounded-lg">
<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
pillow~=11.1.0 # Image handling
whitenoise~=6.6.0 # Static file serving
django-cleanup