Merge branch '163-auf-ahnliche-quizze-verweisen' into 'master'
Resolve "Auf ähnliche Quizze verweisen" Closes #163 See merge request enrichment-2024/qivip!120
This commit is contained in:
45
THIRD_PARTY_LICENSES_PYTHON.md
Normal file
45
THIRD_PARTY_LICENSES_PYTHON.md
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
| Name | Version | License |
|
||||||
|
|---------------------------|--------------|---------------------------------------------------------|
|
||||||
|
| Automat | 25.4.16 | MIT License |
|
||||||
|
| Django | 5.1.13 | BSD License |
|
||||||
|
| Twisted | 25.5.0 | MIT License |
|
||||||
|
| asgiref | 3.10.0 | BSD License |
|
||||||
|
| attrs | 25.4.0 | UNKNOWN |
|
||||||
|
| autobahn | 25.10.1 | UNKNOWN |
|
||||||
|
| certifi | 2025.10.5 | Mozilla Public License 2.0 (MPL 2.0) |
|
||||||
|
| cffi | 2.0.0 | UNKNOWN |
|
||||||
|
| channels | 4.2.2 | BSD License |
|
||||||
|
| channels_redis | 4.3.0 | BSD |
|
||||||
|
| chardet | 5.2.0 | GNU Lesser General Public License v2 or later (LGPLv2+) |
|
||||||
|
| charset-normalizer | 3.4.4 | MIT |
|
||||||
|
| colorama | 0.4.6 | BSD License |
|
||||||
|
| constantly | 23.10.4 | MIT License |
|
||||||
|
| cryptography | 46.0.3 | UNKNOWN |
|
||||||
|
| daphne | 4.1.2 | BSD License |
|
||||||
|
| django-autocomplete-light | 3.12.1 | MIT License |
|
||||||
|
| django-cleanup | 9.0.0 | MIT License |
|
||||||
|
| geographiclib | 2.1 | MIT |
|
||||||
|
| geopy | 2.4.1 | MIT License |
|
||||||
|
| hyperlink | 21.0.0 | MIT License |
|
||||||
|
| idna | 3.11 | UNKNOWN |
|
||||||
|
| incremental | 24.7.2 | MIT License |
|
||||||
|
| msgpack | 1.1.2 | UNKNOWN |
|
||||||
|
| pillow | 11.1.0 | CMU License (MIT-CMU) |
|
||||||
|
| pyOpenSSL | 25.3.0 | Apache Software License |
|
||||||
|
| pyasn1 | 0.6.1 | BSD License |
|
||||||
|
| pyasn1_modules | 0.4.2 | BSD License |
|
||||||
|
| pycparser | 2.23 | BSD License |
|
||||||
|
| pypng | 0.20220715.0 | MIT License |
|
||||||
|
| python-dotenv | 1.1.1 | BSD License |
|
||||||
|
| qrcode | 7.4.2 | BSD License |
|
||||||
|
| redis | 6.4.0 | MIT License |
|
||||||
|
| reportlab | 4.2.5 | BSD License |
|
||||||
|
| requests | 2.32.5 | Apache Software License |
|
||||||
|
| service-identity | 24.2.0 | MIT License |
|
||||||
|
| sqlparse | 0.5.3 | BSD License |
|
||||||
|
| txaio | 25.9.2 | UNKNOWN |
|
||||||
|
| typing_extensions | 4.15.0 | UNKNOWN |
|
||||||
|
| tzdata | 2025.2 | Apache Software License |
|
||||||
|
| urllib3 | 2.5.0 | UNKNOWN |
|
||||||
|
| whitenoise | 6.6.0 | MIT License |
|
||||||
|
| zope.interface | 8.0.1 | Zope Public License |
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
| Name | Version | License |
|
|
||||||
|--------------------|--------------|---------------------------------------------------------|
|
|
||||||
| Automat | 25.4.16 | MIT License |
|
|
||||||
| Django | 5.1.13 | BSD License |
|
|
||||||
| Twisted | 25.5.0 | MIT License |
|
|
||||||
| asgiref | 3.10.0 | BSD License |
|
|
||||||
| attrs | 25.4.0 | UNKNOWN |
|
|
||||||
| autobahn | 25.10.1 | UNKNOWN |
|
|
||||||
| certifi | 2025.10.5 | Mozilla Public License 2.0 (MPL 2.0) |
|
|
||||||
| cffi | 2.0.0 | UNKNOWN |
|
|
||||||
| channels | 4.2.2 | BSD License |
|
|
||||||
| channels_redis | 4.3.0 | BSD |
|
|
||||||
| chardet | 5.2.0 | GNU Lesser General Public License v2 or later (LGPLv2+) |
|
|
||||||
| charset-normalizer | 3.4.4 | MIT |
|
|
||||||
| colorama | 0.4.6 | BSD License |
|
|
||||||
| constantly | 23.10.4 | MIT License |
|
|
||||||
| cryptography | 46.0.3 | UNKNOWN |
|
|
||||||
| daphne | 4.1.2 | BSD License |
|
|
||||||
| django-cleanup | 9.0.0 | MIT License |
|
|
||||||
| geographiclib | 2.1 | MIT |
|
|
||||||
| geopy | 2.4.1 | MIT License |
|
|
||||||
| hyperlink | 21.0.0 | MIT License |
|
|
||||||
| idna | 3.11 | UNKNOWN |
|
|
||||||
| incremental | 24.7.2 | MIT License |
|
|
||||||
| msgpack | 1.1.2 | UNKNOWN |
|
|
||||||
| pillow | 11.1.0 | CMU License (MIT-CMU) |
|
|
||||||
| pyOpenSSL | 25.3.0 | Apache Software License |
|
|
||||||
| pyasn1 | 0.6.1 | BSD License |
|
|
||||||
| pyasn1_modules | 0.4.2 | BSD License |
|
|
||||||
| pycparser | 2.23 | BSD License |
|
|
||||||
| pypng | 0.20220715.0 | MIT License |
|
|
||||||
| python-dotenv | 1.1.1 | BSD License |
|
|
||||||
| qrcode | 7.4.2 | BSD License |
|
|
||||||
| redis | 6.4.0 | MIT License |
|
|
||||||
| reportlab | 4.2.5 | BSD License |
|
|
||||||
| requests | 2.32.5 | Apache Software License |
|
|
||||||
| service-identity | 24.2.0 | MIT License |
|
|
||||||
| sqlparse | 0.5.3 | BSD License |
|
|
||||||
| txaio | 25.9.2 | UNKNOWN |
|
|
||||||
| typing_extensions | 4.15.0 | UNKNOWN |
|
|
||||||
| tzdata | 2025.2 | Apache Software License |
|
|
||||||
| urllib3 | 2.5.0 | UNKNOWN |
|
|
||||||
| whitenoise | 6.6.0 | MIT License |
|
|
||||||
| zope.interface | 8.0.1 | Zope Public License |
|
|
||||||
@@ -57,6 +57,8 @@ INSTALLED_APPS = [
|
|||||||
'channels',
|
'channels',
|
||||||
'django_cleanup',
|
'django_cleanup',
|
||||||
'django.contrib.humanize',
|
'django.contrib.humanize',
|
||||||
|
'dal',
|
||||||
|
'dal_select2',
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
|||||||
@@ -6,6 +6,12 @@ class QivipQuizAdmin(admin.ModelAdmin):
|
|||||||
list_display = ('name','published_at', 'user_id', 'status', 'category', 'creation_date', 'update_date') # Welche Felder sollen in der Übersicht angezeigt werden
|
list_display = ('name','published_at', 'user_id', 'status', 'category', 'creation_date', 'update_date') # Welche Felder sollen in der Übersicht angezeigt werden
|
||||||
search_fields = ('name', 'user_id__username', 'category__name') # Suchfelder
|
search_fields = ('name', 'user_id__username', 'category__name') # Suchfelder
|
||||||
list_filter = ('status', 'category') # Filteroptionen
|
list_filter = ('status', 'category') # Filteroptionen
|
||||||
|
autocomplete_fields = ("reference_quizzes",)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Für das QivipQuestion Modell
|
# Für das QivipQuestion Modell
|
||||||
class QivipQuestionAdmin(admin.ModelAdmin):
|
class QivipQuestionAdmin(admin.ModelAdmin):
|
||||||
list_display = ('id', 'quiz_id', 'data', 'creation_date', 'update_date', 'credits')
|
list_display = ('id', 'quiz_id', 'data', 'creation_date', 'update_date', 'credits')
|
||||||
|
|||||||
@@ -1,17 +1,31 @@
|
|||||||
from django import forms
|
from django import forms
|
||||||
from .models import QivipQuiz, QivipQuestion, QuizCategory
|
from .models import QivipQuiz, QivipQuestion, QuizCategory
|
||||||
|
from dal import autocomplete
|
||||||
|
|
||||||
class QuizForm(forms.ModelForm):
|
class QuizForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = QivipQuiz
|
model = QivipQuiz
|
||||||
fields = ['name', 'description', 'status', 'category','difficulty','credits']
|
fields = ['name', 'description', 'status', 'category','difficulty','reference_quizzes','credits']
|
||||||
|
widgets = {
|
||||||
|
'reference_quizzes': autocomplete.ModelSelect2Multiple(
|
||||||
|
url='library:quiz-autocomplete',
|
||||||
|
forward=['pk']
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(QuizForm, self).__init__(*args, **kwargs)
|
super(QuizForm, self).__init__(*args, **kwargs)
|
||||||
for field in self.fields.values():
|
for field in self.fields.values():
|
||||||
field.widget.attrs.update({
|
field.widget.attrs.update({
|
||||||
'class': 'dark:bg-[#2a2f3a]! dark:text-white!'
|
|
||||||
})
|
})
|
||||||
|
self.fields["reference_quizzes"].queryset = QivipQuiz.objects.filter(
|
||||||
|
status="öffentlich").exclude(pk=self.instance.pk)
|
||||||
|
self.fields["reference_quizzes"].label_from_instance = lambda obj: f"{obj.name} (ID: {obj.pk}) (User: {obj.user_id})"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
18
django/library/migrations/0060_qivipquiz_similar_quizzes.py
Normal file
18
django/library/migrations/0060_qivipquiz_similar_quizzes.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.1.7 on 2025-11-27 18:22
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('library', '0059_remove_qivipquiz_single_player_or_multiple'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='qivipquiz',
|
||||||
|
name='similar_quizzes',
|
||||||
|
field=models.ManyToManyField(blank=True, related_name='similar_to', to='library.qivipquiz'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.1.7 on 2025-11-27 18:22
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('library', '0060_qivipquiz_similar_quizzes'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='qivipquiz',
|
||||||
|
name='similar_quizzes',
|
||||||
|
field=models.ManyToManyField(blank=True, to='library.qivipquiz'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.1.7 on 2025-11-27 19:54
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('library', '0061_alter_qivipquiz_similar_quizzes'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='qivipquiz',
|
||||||
|
name='similar_quizzes',
|
||||||
|
field=models.ManyToManyField(blank=True, to='library.qivipquiz', verbose_name='Verweis auf andere Quizze'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.1.7 on 2025-12-03 11:02
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('library', '0062_alter_qivipquiz_similar_quizzes'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='qivipquiz',
|
||||||
|
old_name='similar_quizzes',
|
||||||
|
new_name='reference_quizzes',
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -43,6 +43,12 @@ class QivipQuiz(models.Model):
|
|||||||
on_delete=models.PROTECT,
|
on_delete=models.PROTECT,
|
||||||
related_name="quizzes"
|
related_name="quizzes"
|
||||||
)
|
)
|
||||||
|
reference_quizzes = models.ManyToManyField(
|
||||||
|
'self',
|
||||||
|
blank=True,
|
||||||
|
symmetrical=False,
|
||||||
|
verbose_name="Verweis auf andere Quizze"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
quiz_played_Lernmodus = models.IntegerField(null=True, blank=True, default=0)
|
quiz_played_Lernmodus = models.IntegerField(null=True, blank=True, default=0)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ from django.urls import path
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from . import views
|
from . import views
|
||||||
from django.conf.urls.static import static
|
from django.conf.urls.static import static
|
||||||
|
from .views import QuizAutocomplete
|
||||||
app_name = 'library'
|
app_name = 'library'
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
@@ -20,7 +21,11 @@ urlpatterns = [
|
|||||||
path('detail/copy/<int:pk>/', views.copy_quiz, name='copy_quiz'),
|
path('detail/copy/<int:pk>/', views.copy_quiz, name='copy_quiz'),
|
||||||
path('favorite_quiz/<int:pk>/', views.favorite_quiz, name='favorite_quiz'),
|
path('favorite_quiz/<int:pk>/', views.favorite_quiz, name='favorite_quiz'),
|
||||||
path("quiz-names-json/", views.quiz_names_json, name="quiz_names_json"),
|
path("quiz-names-json/", views.quiz_names_json, name="quiz_names_json"),
|
||||||
#path('quiz/<int:pk>/pdf/', views.pdf_solution, name='quiz_solution'),
|
path(
|
||||||
#path('quiz/<int:pk>/pdf/task', views.pdf_task, name='quiz_task'),
|
"autocomplete/quiz",
|
||||||
|
QuizAutocomplete.as_view(),
|
||||||
|
name="quiz-autocomplete"
|
||||||
|
),
|
||||||
|
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -40,6 +40,37 @@ from PIL import Image as PILImage, ImageOps
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
import os
|
import os
|
||||||
from django.utils.html import escape
|
from django.utils.html import escape
|
||||||
|
from .models import QivipQuiz
|
||||||
|
from django.db.models import Value, CharField
|
||||||
|
from django.db.models.functions import Concat
|
||||||
|
# views.py
|
||||||
|
from dal import autocomplete
|
||||||
|
from .models import QivipQuiz
|
||||||
|
|
||||||
|
class QuizAutocomplete(autocomplete.Select2QuerySetView):
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
qs = QivipQuiz.objects.filter(status="öffentlich")
|
||||||
|
|
||||||
|
pk = self.forwarded.get('pk', None)
|
||||||
|
if pk:
|
||||||
|
qs = qs.exclude(pk=pk)
|
||||||
|
|
||||||
|
if self.q:
|
||||||
|
qs = qs.annotate(
|
||||||
|
search_text=Concat(
|
||||||
|
'name',
|
||||||
|
Value(' (ID: '), 'pk', Value(') (User: '), 'user_id', Value(')'),
|
||||||
|
output_field=CharField()
|
||||||
|
)
|
||||||
|
).filter(search_text__icontains=self.q)
|
||||||
|
return qs
|
||||||
|
|
||||||
|
def get_result_label(self, result):
|
||||||
|
# z.B. Name + ID + User
|
||||||
|
return f"{result.name} (ID: {result.pk}) (User: {result.user_id})"
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def pdf_solution(request, pk):
|
def pdf_solution(request, pk):
|
||||||
quiz = get_object_or_404(QivipQuiz, pk=pk)
|
quiz = get_object_or_404(QivipQuiz, pk=pk)
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
@import 'tailwindcss';
|
@import 'tailwindcss';
|
||||||
|
|
||||||
|
.select2-container {
|
||||||
|
@apply font-black!;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
qp-container {
|
qp-container {
|
||||||
@apply max-w-xl w-full mx-auto;
|
@apply max-w-xl w-full mx-auto;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -319,65 +319,61 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-end">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<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-Infos
|
||||||
|
</p>
|
||||||
|
<div class="flex">
|
||||||
{% if quiz.base_quiz %}
|
{% if quiz.base_quiz %}
|
||||||
<p class="text-gray-600 mt-2 dark:text-white">Bearbeitung:<span class="text-blue-600 font-bold"> <a href="{% url 'library:overview_quiz' %}?filter=1&user={{ quiz.user_id }}">{{ quiz.user_id }}</a></span></p>
|
<p class="text-gray-600 mt-2 dark:text-white">Bearbeitung:<span class="font-bold"> <a href="{% url 'library:overview_quiz' %}?filter=1&user={{ quiz.user_id }}">{{ quiz.user_id }}</a></span></p>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p class="text-gray-600 mt-2 dark:text-white">Autor:<span class="text-blue-600 font-bold"> <a href="{% url 'library:overview_quiz' %}?filter=1&user={{ quiz.user_id }}">{{ quiz.user_id }}</a></span></p>
|
<p class="text-gray-600 mt-2 dark:text-white">Autor:<span class="font-bold"> <a href="{% url 'library:overview_quiz' %}?filter=1&user={{ quiz.user_id }}">{{ quiz.user_id }}</a></span></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-end">
|
<div class="flex">
|
||||||
{% if quiz.base_quiz %}
|
{% if quiz.base_quiz %}
|
||||||
<p class="text-gray-600 dark:text-white ">Kopie von: <a href="{% url 'library:detail_quiz' quiz.base_quiz.id %}"><span class="text-blue-600 font-bold">{{ quiz.base_quiz}}</span></a></p>
|
<p class="text-gray-600 dark:text-white ">Kopie von: <a href="{% url 'library:detail_quiz' quiz.base_quiz.id %}"><span class="font-bold">{{ quiz.base_quiz}}</span></a></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-end">
|
<div class="flex">
|
||||||
{% if quiz.base_quiz %}
|
{% if quiz.base_quiz %}
|
||||||
<p class="text-gray-600 dark:text-white">Autor:<span class="text-blue-600 font-bold"> <a href="{% url 'library:overview_quiz' %}?filter=1&user={{ quiz.base_quiz.user_id }}">{{ quiz.base_quiz.user_id }}</a></span></p>
|
<p class="text-gray-600 dark:text-white">Autor:<span class="font-bold"> <a href="{% url 'library:overview_quiz' %}?filter=1&user={{ quiz.base_quiz.user_id }}">{{ quiz.base_quiz.user_id }}</a></span></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Links müssen wieder ergänzt werden!
|
|
||||||
{% if questions %}
|
|
||||||
<div class="flex flex-col sm:flex-row gap-4 items-start sm:items-center my-6">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a href=""
|
|
||||||
target="_blank"
|
|
||||||
class=" inline-flex items-center gap-2 px-2 py-2 rounded-lg bg-blue-600 hover:bg-blue-700 text-white shadow-md transition">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none"
|
|
||||||
viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
||||||
d="M12 4v16m8-8H4" />
|
|
||||||
</svg>
|
|
||||||
als Aufgabenblatt herunterladen (PDF)
|
|
||||||
</a>
|
|
||||||
|
|
||||||
|
|
||||||
<a href=""
|
|
||||||
target="_blank"
|
|
||||||
class="inline-flex items-center gap-2 px-2 py-2 rounded-lg bg-green-600 hover:bg-green-700 text-white shadow-md transition">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none"
|
|
||||||
viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
||||||
d="M12 4v16m8-8H4" />
|
|
||||||
</svg>
|
|
||||||
Lösungen herunterladen (PDF)
|
|
||||||
</a>
|
|
||||||
|
|
||||||
|
<div class="flex">
|
||||||
|
|
||||||
|
<p class="text-gray-600 dark:text-white">Quiz ID:<span class="font-bold"> {{ quiz.pk }}</span></p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
|
||||||
-->
|
|
||||||
|
{% if quiz.reference_quizzes.all %}
|
||||||
|
<div class="flex">
|
||||||
|
<p class="text-gray-600 dark:text-white">Verweis auf andere Quizze:
|
||||||
|
<span class="font-bold">
|
||||||
|
{% for reference in quiz.reference_quizzes.all %}
|
||||||
|
<a href="{% url 'library:detail_quiz' reference.id %}">{{ reference.name}}</a>{% if not forloop.last %}, {% endif %}
|
||||||
|
{% empty %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
</span></p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="max-w-full p-4 mt-8 rounded-2xl bg-gray-100 dark:bg-transparent shadow-sm">
|
<div class="max-w-full p-4 mt-8 rounded-2xl bg-gray-100 dark:bg-transparent shadow-sm">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="flex flex-col max-w-full">
|
<div class="flex flex-col max-w-full">
|
||||||
<p class="text-lg font-bold text-gray-800 dark:text-white dark:bg-transparent mb-3">
|
<p class="text-lg font-bold text-gray-800 dark:text-white dark:bg-transparent mb-3">
|
||||||
Credits
|
Credits
|
||||||
|
|||||||
@@ -1,43 +1,97 @@
|
|||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %} {% block content %}
|
||||||
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
|
{{ form.media }}
|
||||||
|
<style>
|
||||||
|
|
||||||
|
|
||||||
{% block content %}
|
.select2-container {
|
||||||
|
width: 100% !important;
|
||||||
|
min-width: 0; /* verhindert Überlaufen bei kleinen Screens */
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Das Auswahlfeld */
|
||||||
|
.select2-selection {
|
||||||
|
width: 100% !important;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Angezeigter Text im Auswahlfeld */
|
||||||
|
.select2-selection__rendered {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-selection__choice {
|
||||||
|
white-space: normal;
|
||||||
|
word-break: break-word;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="container mx-auto px-4 py-4">
|
|
||||||
<div class="max-w-lg field-group mx-auto bg-white rounded-lg shadow-md p-6 border-blue-600 border-2 rounded-xl shadow-md dark:bg-transparent dark:text-white">
|
|
||||||
<form method="post" enctype="multipart/form-data" class="dark-form space-y-4">
|
|
||||||
{% csrf_token %}
|
|
||||||
{{ form.as_p }}
|
|
||||||
|
|
||||||
{% if form.instance.image %}
|
|
||||||
<img src="{{ form.instance.image.image.url }}" style="max-width: 100px;" alt="Bild der Frage">
|
|
||||||
<label for="reset_image">
|
|
||||||
<input type="checkbox" name="reset_image" id="reset_image">
|
|
||||||
Bild zurücksetzen
|
|
||||||
</label>
|
|
||||||
{% endif %}
|
|
||||||
<div>
|
|
||||||
<label class="font-bold" for="quiz_image">Bild:</label>
|
|
||||||
<input class="max-w-full bg-blue-200 p-2 m-2 rounded-lg border-2 border-blue-400 dark:bg-transparent" type="file" name="quiz_image" id="quiz_image">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="text-center text-gray-600 text-sm dislay-flex align-bottom">
|
|
||||||
<label class=''>Mit der Erstellung von diesem Quiz stimmen Sie der <a class="text-blue-600" href="/privacy">Datenschutzerklärung </a> zu.</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex justify-center space-x-3">
|
</style>
|
||||||
<a href="{% if object.quiz_id %}{% url 'library:detail_quiz' object.quiz_id.id %}{% else %}{% url 'library:overview_quiz' %}{% endif %}"
|
|
||||||
class="inline-flex items-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
|
<input type="hidden" name="pk" value="{{ form.instance.pk }}" />
|
||||||
Abbrechen
|
|
||||||
</a>
|
<div class="container mx-auto px-4 py-4">
|
||||||
<button type="submit"
|
<div
|
||||||
class="inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
|
class="max-w-lg field-group mx-auto bg-white rounded-lg shadow-md p-6 border-blue-600 border-2 rounded-xl shadow-md dark:bg-transparent dark:text-white"
|
||||||
Speichern
|
>
|
||||||
</button>
|
<form
|
||||||
</div>
|
method="post"
|
||||||
|
enctype="multipart/form-data"
|
||||||
|
class="dark-form space-y-4"
|
||||||
|
>
|
||||||
|
{% csrf_token %} {{ form.as_p }} {% if form.instance.image %}
|
||||||
|
<img
|
||||||
|
src="{{ form.instance.image.image.url }}"
|
||||||
|
style="max-width: 100px"
|
||||||
|
alt="Bild der Frage"
|
||||||
|
/>
|
||||||
|
<label for="reset_image">
|
||||||
|
<input type="checkbox" name="reset_image" id="reset_image" />
|
||||||
|
Bild zurücksetzen
|
||||||
|
</label>
|
||||||
|
{% endif %}
|
||||||
|
<div>
|
||||||
|
<label class="font-bold" for="quiz_image">Bild:</label>
|
||||||
|
<input
|
||||||
|
class="max-w-full bg-blue-200 p-2 m-2 rounded-lg border-2 border-blue-400 dark:bg-transparent"
|
||||||
|
type="file"
|
||||||
|
name="quiz_image"
|
||||||
|
id="quiz_image"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-center text-gray-600 text-sm dislay-flex align-bottom">
|
||||||
|
<label class=""
|
||||||
|
>Mit der Erstellung von diesem Quiz stimmen Sie der
|
||||||
|
<a class="text-blue-600" href="/privacy">Datenschutzerklärung </a>
|
||||||
|
zu.</label
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-center space-x-3">
|
||||||
|
<a
|
||||||
|
href="{% if object.quiz_id %}{% url 'library:detail_quiz' object.quiz_id.id %}{% else %}{% url 'library:overview_quiz' %}{% endif %}"
|
||||||
|
class="inline-flex items-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
|
||||||
|
>
|
||||||
|
Abbrechen
|
||||||
|
</a>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
|
||||||
|
>
|
||||||
|
Speichern
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -14,3 +14,4 @@ pip-licenses ~= 5.0.0
|
|||||||
requests
|
requests
|
||||||
requests
|
requests
|
||||||
geopy
|
geopy
|
||||||
|
django-autocomplete-light
|
||||||
|
|||||||
Reference in New Issue
Block a user