mirror of
https://github.com/MarijnDoeve/TijdVoorDeTest.git
synced 2026-03-06 12:44:20 +01:00
progress
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
from django.contrib import admin
|
||||
|
||||
from .models import Question, Answer, Candidate, Quiz, Season, GivenAnswer
|
||||
from .models import Answer, Candidate, GivenAnswer, Question, Quiz, Season
|
||||
|
||||
|
||||
class CandidatesAdmin(admin.StackedInline):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import base64
|
||||
import binascii
|
||||
|
||||
from .models import Season, Candidate
|
||||
from .models import Candidate, Season
|
||||
|
||||
|
||||
class SeasonCodeConverter:
|
||||
|
||||
@@ -1136,6 +1136,30 @@
|
||||
"name": "Tom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "quiz.candidate",
|
||||
"pk": 14,
|
||||
"fields": {
|
||||
"season": 1,
|
||||
"name": "Marijn"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "quiz.candidate",
|
||||
"pk": 15,
|
||||
"fields": {
|
||||
"season": 1,
|
||||
"name": "Renske"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "quiz.candidate",
|
||||
"pk": 16,
|
||||
"fields": {
|
||||
"season": 1,
|
||||
"name": "Philine"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "quiz.quiz",
|
||||
"pk": 1,
|
||||
|
||||
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-10-20 00:23+0200\n"
|
||||
"POT-Creation-Date: 2024-11-25 19:18+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -18,93 +18,77 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: quiz/models/answer.py:10
|
||||
msgid "text"
|
||||
msgstr "tekst"
|
||||
|
||||
#: quiz/models/answer.py:15 quiz/models/given_answer.py:21
|
||||
#: quiz/models/question.py:9 quiz/models/question.py:21
|
||||
msgid "question"
|
||||
msgstr "vraag"
|
||||
|
||||
#: quiz/models/answer.py:17
|
||||
msgid "is right answer"
|
||||
msgstr "is goede antwoord"
|
||||
|
||||
#: quiz/models/answer.py:19 quiz/models/candidate.py:25
|
||||
msgid "candidates"
|
||||
msgstr "kandidaten"
|
||||
|
||||
#: quiz/models/answer.py:23 quiz/models/given_answer.py:24
|
||||
msgid "answer"
|
||||
msgstr "antwoord"
|
||||
|
||||
#: quiz/models/answer.py:24
|
||||
msgid "answers"
|
||||
msgstr "antwoorden"
|
||||
|
||||
#: quiz/models/candidate.py:15 quiz/models/quiz.py:9 quiz/models/season.py:12
|
||||
msgid "name"
|
||||
msgstr "naam"
|
||||
|
||||
#: quiz/models/candidate.py:24 quiz/models/correction.py:14
|
||||
#: quiz/models/given_answer.py:15 quiz/models/quiz_time.py:11
|
||||
msgid "candidate"
|
||||
msgstr "kandidaat"
|
||||
|
||||
#: quiz/models/correction.py:20 quiz/models/question.py:11
|
||||
#: quiz/models/quiz.py:26 quiz/models/quiz_time.py:13
|
||||
#: quiz/apps.py:8 quiz/models/correction.py:17 quiz/models/given_answer.py:19
|
||||
#: quiz/models/question.py:20 quiz/models/quiz.py:24
|
||||
msgid "quiz"
|
||||
msgstr "test"
|
||||
|
||||
#: quiz/models/correction.py:25
|
||||
#: quiz/models/answer.py:7
|
||||
msgid "text"
|
||||
msgstr "tekst"
|
||||
|
||||
#: quiz/models/answer.py:12 quiz/models/question.py:15
|
||||
#: quiz/models/question.py:28
|
||||
msgid "question"
|
||||
msgstr "vraag"
|
||||
|
||||
#: quiz/models/answer.py:14
|
||||
msgid "is right answer"
|
||||
msgstr "is goede antwoord"
|
||||
|
||||
#: quiz/models/answer.py:16 quiz/models/candidate.py:50
|
||||
msgid "candidates"
|
||||
msgstr "kandidaten"
|
||||
|
||||
#: quiz/models/answer.py:20 quiz/models/given_answer.py:25
|
||||
msgid "answer"
|
||||
msgstr "antwoord"
|
||||
|
||||
#: quiz/models/answer.py:21
|
||||
msgid "answers"
|
||||
msgstr "antwoorden"
|
||||
|
||||
#: quiz/models/candidate.py:18 quiz/models/quiz.py:7 quiz/models/season.py:12
|
||||
msgid "name"
|
||||
msgstr "naam"
|
||||
|
||||
#: quiz/models/candidate.py:49 quiz/models/correction.py:11
|
||||
#: quiz/models/given_answer.py:11
|
||||
msgid "candidate"
|
||||
msgstr "kandidaat"
|
||||
|
||||
#: quiz/models/correction.py:22
|
||||
msgid "correction"
|
||||
msgstr "joker"
|
||||
|
||||
#: quiz/models/correction.py:26
|
||||
#: quiz/models/correction.py:23
|
||||
msgid "corrections"
|
||||
msgstr "jokers"
|
||||
|
||||
#: quiz/models/given_answer.py:30
|
||||
#: quiz/models/given_answer.py:36
|
||||
msgid "given answer"
|
||||
msgstr "gegeven antwoord"
|
||||
|
||||
#: quiz/models/given_answer.py:31
|
||||
#: quiz/models/given_answer.py:37
|
||||
msgid "given answers"
|
||||
msgstr "gegeven antwoorden"
|
||||
|
||||
#: quiz/models/question.py:13
|
||||
msgid "number"
|
||||
msgstr "nummer"
|
||||
|
||||
#: quiz/models/question.py:14
|
||||
msgid "enabled"
|
||||
msgstr "ingeschakeld"
|
||||
|
||||
#: quiz/models/question.py:22
|
||||
msgid "enabled"
|
||||
msgstr "actief"
|
||||
|
||||
#: quiz/models/question.py:29
|
||||
msgid "questions"
|
||||
msgstr "vraag"
|
||||
|
||||
#: quiz/models/quiz.py:14 quiz/models/season.py:38
|
||||
#: quiz/models/quiz.py:12 quiz/models/season.py:38
|
||||
msgid "season"
|
||||
msgstr "seizoen"
|
||||
|
||||
#: quiz/models/quiz.py:27
|
||||
#: quiz/models/quiz.py:25
|
||||
msgid "quizzes"
|
||||
msgstr "tests"
|
||||
|
||||
#: quiz/models/quiz_time.py:14
|
||||
msgid "seconds"
|
||||
msgstr "seconden"
|
||||
|
||||
#: quiz/models/quiz_time.py:17
|
||||
msgid "quiz time"
|
||||
msgstr "testtijd"
|
||||
|
||||
#: quiz/models/quiz_time.py:18
|
||||
msgid "quiz times"
|
||||
msgstr "testtijden"
|
||||
|
||||
#: quiz/models/season.py:19
|
||||
msgid "active quiz"
|
||||
msgstr "actieve test"
|
||||
@@ -120,3 +104,35 @@ msgstr "kandidaten voorregistreren"
|
||||
#: quiz/models/season.py:39
|
||||
msgid "seasons"
|
||||
msgstr "seizoenen"
|
||||
|
||||
#: quiz/templates/quiz/question.html:11
|
||||
msgid "Weirdly enough this question has no answers..."
|
||||
msgstr "Raar genoeg heeft deze vraag geen antwoorden..."
|
||||
|
||||
#: quiz/templates/quiz/select_season.html:4
|
||||
msgid "Tijd voor de test"
|
||||
msgstr "Tijd voor de test"
|
||||
|
||||
#: quiz/views/enternameview.py:14
|
||||
msgid "Name"
|
||||
msgstr "Naam"
|
||||
|
||||
#: quiz/views/enternameview.py:27
|
||||
msgid "This season has no active quiz."
|
||||
msgstr "Dit seizoen heeft geen actieve test."
|
||||
|
||||
#: quiz/views/enternameview.py:39
|
||||
msgid "Candidate does not exist"
|
||||
msgstr "Kandidaat bestaat niet"
|
||||
|
||||
#: quiz/views/questionview.py:23
|
||||
msgid "No active quiz for season"
|
||||
msgstr "Geen active test voor seizoen"
|
||||
|
||||
#: quiz/views/questionview.py:27
|
||||
msgid "Quiz done"
|
||||
msgstr "Test klaar"
|
||||
|
||||
#: quiz/views/selectseasonview.py:30
|
||||
msgid "Invalid season code"
|
||||
msgstr "Ongeldige seizoencode"
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
# Generated by Django 5.1.2 on 2024-10-19 21:54
|
||||
# Generated by Django 5.1.3 on 2024-11-25 18:17
|
||||
|
||||
import django.db.models.deletion
|
||||
import quiz.helpers
|
||||
from django.db import migrations, models
|
||||
|
||||
import quiz.helpers
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
@@ -24,7 +25,7 @@ class Migration(migrations.Migration):
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("name", models.CharField(max_length=16, verbose_name="naam")),
|
||||
("name", models.CharField(max_length=16, verbose_name="name")),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "candidate",
|
||||
@@ -44,7 +45,6 @@ class Migration(migrations.Migration):
|
||||
),
|
||||
),
|
||||
("question", models.CharField(max_length=256, verbose_name="question")),
|
||||
("number", models.PositiveSmallIntegerField(verbose_name="number")),
|
||||
("enabled", models.BooleanField(default=True, verbose_name="enabled")),
|
||||
],
|
||||
options={
|
||||
@@ -64,7 +64,7 @@ class Migration(migrations.Migration):
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("name", models.CharField(max_length=64, verbose_name="naam")),
|
||||
("name", models.CharField(max_length=64, verbose_name="name")),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "quiz",
|
||||
@@ -91,7 +91,7 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"candidates",
|
||||
models.ManyToManyField(
|
||||
to="quiz.candidate", verbose_name="candidates"
|
||||
blank=True, to="quiz.candidate", verbose_name="candidates"
|
||||
),
|
||||
),
|
||||
(
|
||||
@@ -107,6 +107,7 @@ class Migration(migrations.Migration):
|
||||
options={
|
||||
"verbose_name": "answer",
|
||||
"verbose_name_plural": "answers",
|
||||
"order_with_respect_to": "question",
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
@@ -120,7 +121,7 @@ class Migration(migrations.Migration):
|
||||
),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="QuizTime",
|
||||
name="GivenAnswer",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
@@ -131,11 +132,21 @@ class Migration(migrations.Migration):
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("seconds", models.PositiveIntegerField(verbose_name="seconds")),
|
||||
("created", models.DateTimeField(auto_now_add=True)),
|
||||
(
|
||||
"answer",
|
||||
models.ForeignKey(
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="quiz.answer",
|
||||
verbose_name="answer",
|
||||
),
|
||||
),
|
||||
(
|
||||
"candidate",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="answers",
|
||||
to="quiz.candidate",
|
||||
verbose_name="candidate",
|
||||
),
|
||||
@@ -144,14 +155,16 @@ class Migration(migrations.Migration):
|
||||
"quiz",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="+",
|
||||
to="quiz.quiz",
|
||||
verbose_name="quiz",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "quiz time",
|
||||
"verbose_name_plural": "quiz times",
|
||||
"verbose_name": "given answer",
|
||||
"verbose_name_plural": "given answers",
|
||||
"ordering": ("quiz", "candidate"),
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
@@ -166,7 +179,7 @@ class Migration(migrations.Migration):
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("name", models.CharField(max_length=64, verbose_name="naam")),
|
||||
("name", models.CharField(max_length=64, verbose_name="name")),
|
||||
(
|
||||
"season_code",
|
||||
models.CharField(
|
||||
@@ -175,9 +188,16 @@ class Migration(migrations.Migration):
|
||||
verbose_name="season code",
|
||||
),
|
||||
),
|
||||
(
|
||||
"preregister_candidates",
|
||||
models.BooleanField(
|
||||
default=True, verbose_name="preregister candidates"
|
||||
),
|
||||
),
|
||||
(
|
||||
"active_quiz",
|
||||
models.ForeignKey(
|
||||
blank=True,
|
||||
default=None,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
@@ -212,54 +232,9 @@ class Migration(migrations.Migration):
|
||||
verbose_name="season",
|
||||
),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="GivenAnswer",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"answer",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="quiz.answer",
|
||||
verbose_name="answer",
|
||||
),
|
||||
),
|
||||
(
|
||||
"candidate",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="answers",
|
||||
to="quiz.candidate",
|
||||
verbose_name="candidate",
|
||||
),
|
||||
),
|
||||
(
|
||||
"question",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="given_answers",
|
||||
to="quiz.question",
|
||||
verbose_name="question",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "given answer",
|
||||
"verbose_name_plural": "given answers",
|
||||
"unique_together": {("candidate", "question")},
|
||||
},
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
migrations.AlterOrderWithRespectTo(
|
||||
name="question",
|
||||
unique_together={("quiz", "number")},
|
||||
order_with_respect_to="quiz",
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Correction",
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
# Generated by Django 5.1.2 on 2024-10-19 22:17
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("quiz", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="season",
|
||||
name="preregister_candidates",
|
||||
field=models.BooleanField(
|
||||
default=True, verbose_name="preregister candidates"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="answer",
|
||||
name="candidates",
|
||||
field=models.ManyToManyField(
|
||||
blank=True, to="quiz.candidate", verbose_name="candidates"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="candidate",
|
||||
name="name",
|
||||
field=models.CharField(max_length=16, verbose_name="name"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="quiz",
|
||||
name="name",
|
||||
field=models.CharField(max_length=64, verbose_name="name"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="season",
|
||||
name="active_quiz",
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
default=None,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
related_name="+",
|
||||
to="quiz.quiz",
|
||||
verbose_name="active quiz",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="season",
|
||||
name="name",
|
||||
field=models.CharField(max_length=64, verbose_name="name"),
|
||||
),
|
||||
]
|
||||
@@ -1,31 +0,0 @@
|
||||
# Generated by Django 5.1.2 on 2024-11-03 19:21
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("quiz", "0002_season_preregister_candidates_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="givenanswer",
|
||||
name="created",
|
||||
field=models.DateTimeField(auto_now_add=True, default=None),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="givenanswer",
|
||||
name="question",
|
||||
field=models.ForeignKey(
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="given_answers",
|
||||
to="quiz.question",
|
||||
verbose_name="question",
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -1,29 +0,0 @@
|
||||
# Generated by Django 5.1.3 on 2024-11-23 16:15
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("quiz", "0003_givenanswer_created_alter_givenanswer_question"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterUniqueTogether(
|
||||
name="question",
|
||||
unique_together=set(),
|
||||
),
|
||||
migrations.AlterOrderWithRespectTo(
|
||||
name="question",
|
||||
order_with_respect_to="quiz",
|
||||
),
|
||||
migrations.AlterOrderWithRespectTo(
|
||||
name="answer",
|
||||
order_with_respect_to="question",
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name="question",
|
||||
name="number",
|
||||
),
|
||||
]
|
||||
@@ -4,5 +4,4 @@ from .correction import Correction
|
||||
from .given_answer import GivenAnswer
|
||||
from .question import Question
|
||||
from .quiz import Quiz
|
||||
from .quiz_time import QuizTime
|
||||
from .season import Season
|
||||
|
||||
@@ -5,7 +5,7 @@ from django.utils.translation import gettext_lazy as _
|
||||
from django_stubs_ext.db.models import TypedModelMeta
|
||||
|
||||
from .given_answer import GivenAnswer
|
||||
from .question import NoActiveTestForSeason, QuizAlreadyFinished, Question
|
||||
from .question import NoActiveTestForSeason, Question, QuizAlreadyFinished
|
||||
|
||||
|
||||
class Candidate(models.Model):
|
||||
@@ -23,11 +23,13 @@ class Candidate(models.Model):
|
||||
raise NoActiveTestForSeason()
|
||||
|
||||
question = (
|
||||
Question.objects.filter(quiz=quiz)
|
||||
Question.objects.filter(quiz=quiz, enabled=True)
|
||||
.exclude(
|
||||
id__in=GivenAnswer.objects.filter(
|
||||
candidate=candidate, question__quiz=quiz
|
||||
).values_list("question_id", flat=True)
|
||||
candidate=candidate,
|
||||
quiz=quiz,
|
||||
answer__isnull=False,
|
||||
).values_list("answer__question_id", flat=True)
|
||||
)
|
||||
.first()
|
||||
)
|
||||
|
||||
@@ -2,9 +2,6 @@ from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django_stubs_ext.db.models import TypedModelMeta
|
||||
|
||||
from .candidate import Candidate
|
||||
from .quiz import Quiz
|
||||
|
||||
|
||||
class Correction(models.Model):
|
||||
candidate = models.ForeignKey(
|
||||
|
||||
@@ -10,20 +10,28 @@ class GivenAnswer(models.Model):
|
||||
related_name="answers",
|
||||
verbose_name=_("candidate"),
|
||||
)
|
||||
question = models.ForeignKey(
|
||||
"Question",
|
||||
|
||||
quiz = models.ForeignKey(
|
||||
"Quiz",
|
||||
on_delete=models.CASCADE,
|
||||
null=True,
|
||||
related_name="given_answers",
|
||||
verbose_name=_("question"),
|
||||
null=False,
|
||||
related_name="+",
|
||||
verbose_name=_("quiz"),
|
||||
)
|
||||
|
||||
answer = models.ForeignKey(
|
||||
"Answer", on_delete=models.CASCADE, verbose_name=_("answer")
|
||||
"Answer",
|
||||
on_delete=models.CASCADE,
|
||||
verbose_name=_("answer"),
|
||||
null=True,
|
||||
)
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.quiz} - {self.candidate.name} {self.answer}"
|
||||
|
||||
class Meta(TypedModelMeta):
|
||||
unique_together = ["candidate", "question"]
|
||||
ordering = ("quiz", "candidate")
|
||||
|
||||
verbose_name = _("given answer")
|
||||
verbose_name_plural = _("given answers")
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django_stubs_ext.db.models import TypedModelMeta
|
||||
|
||||
|
||||
class QuizTime(models.Model):
|
||||
candidate = models.ForeignKey(
|
||||
"Candidate", on_delete=models.CASCADE, verbose_name=_("candidate")
|
||||
)
|
||||
quiz = models.ForeignKey("Quiz", on_delete=models.CASCADE, verbose_name=_("quiz"))
|
||||
seconds = models.PositiveIntegerField(verbose_name=_("seconds"))
|
||||
|
||||
class Meta(TypedModelMeta):
|
||||
verbose_name = _("quiz time")
|
||||
verbose_name_plural = _("quiz times")
|
||||
@@ -1,6 +1,6 @@
|
||||
{% load static %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="en" data-bs-theme="dark">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
{# <script src="https://cdn.tailwindcss.com"></script>#}
|
||||
@@ -17,17 +17,33 @@
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-color: black;
|
||||
color: white;
|
||||
|
||||
display: grid;
|
||||
align-items: center;
|
||||
justify-self: center;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.asteriskField {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
{% block body %}{% endblock %}
|
||||
</div>
|
||||
{% block script %}{% endblock %}
|
||||
<main>
|
||||
<div class="container">
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
<div class="alert alert-dismissible fade show {{ message.tags }}" role="alert">
|
||||
{% if message.level == DEFAULT_MESSAGE_LEVELS.DEBUG %}
|
||||
<strong>Debug: </strong>{% endif %}{{ message }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% block body %}{% endblock %}
|
||||
</div>
|
||||
{% block script %}{% endblock %}
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
{% block body %}
|
||||
|
||||
<p>{{ season.name }} ({{ season.season_code }})</p>
|
||||
{% crispy form %}
|
||||
|
||||
{% endblock %}
|
||||
@@ -2,8 +2,8 @@ from django.urls import path, register_converter
|
||||
|
||||
from .converters import CandidateConverter, SeasonCodeConverter
|
||||
from .views import SelectSeasonView
|
||||
from .views.questionview import QuestionView
|
||||
from .views.enternameview import EnterNameView
|
||||
from .views.questionview import QuestionView
|
||||
|
||||
register_converter(SeasonCodeConverter, "season")
|
||||
register_converter(CandidateConverter, "candidate")
|
||||
|
||||
@@ -1,47 +1,47 @@
|
||||
from crispy_forms.helper import FormHelper
|
||||
from django import forms
|
||||
from django.http import Http404
|
||||
from django.shortcuts import render, redirect
|
||||
from django.contrib import messages
|
||||
from django.shortcuts import redirect
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext as _
|
||||
from django.utils.translation import gettext_lazy
|
||||
from django.views import View
|
||||
from django.views.generic.base import TemplateResponseMixin
|
||||
|
||||
from ..models import Season, Candidate
|
||||
from ..models import Candidate, Season
|
||||
|
||||
|
||||
class EnterNameForm(forms.Form):
|
||||
name = forms.CharField()
|
||||
name = forms.CharField(label=_("Name"))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.helper = FormHelper()
|
||||
|
||||
|
||||
class EnterNameView(View):
|
||||
class EnterNameView(View, TemplateResponseMixin):
|
||||
template_name = "quiz/enter_name.html"
|
||||
forms_class = EnterNameForm
|
||||
|
||||
def get(self, request, season: Season, *args, **kwargs):
|
||||
if season.active_quiz == None:
|
||||
raise Http404("No quiz active")
|
||||
messages.info(request, _("This season has no active quiz."))
|
||||
return redirect("home")
|
||||
|
||||
return render(
|
||||
request,
|
||||
self.template_name,
|
||||
{"form": self.forms_class(), "season": season},
|
||||
)
|
||||
return self.render_to_response({"form": self.forms_class()})
|
||||
|
||||
def post(self, request, season: Season, *args, **kwargs):
|
||||
name = request.POST.get("name")
|
||||
|
||||
if season.preregister_candidates:
|
||||
try:
|
||||
candidate = Candidate.objects.get(season=season, name=name)
|
||||
except Candidate.DoesNotExist:
|
||||
raise Http404("Candidate not found")
|
||||
else:
|
||||
candidate, created = Candidate.objects.get_or_create(
|
||||
season=season, name=name
|
||||
)
|
||||
try:
|
||||
candidate = Candidate.objects.get(season=season, name__iexact=name)
|
||||
except Candidate.DoesNotExist:
|
||||
if season.preregister_candidates:
|
||||
messages.warning(request, _("Candidate does not exist"))
|
||||
|
||||
return redirect(reverse("quiz", kwargs={"season": season}))
|
||||
|
||||
candidate = Candidate.objects.create(season=season, name=name)
|
||||
|
||||
return redirect(
|
||||
reverse(
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
from django.contrib import messages
|
||||
from django.core.exceptions import BadRequest
|
||||
from django.http import Http404, HttpRequest, HttpResponse
|
||||
from django.shortcuts import render
|
||||
from django.shortcuts import redirect
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext as _
|
||||
from django.views import View
|
||||
from django.views.generic.base import TemplateResponseMixin
|
||||
|
||||
from ..models import Candidate, Answer, GivenAnswer
|
||||
from ..models.question import NoActiveTestForSeason
|
||||
from ..models import Answer, Candidate, GivenAnswer
|
||||
from ..models.question import NoActiveTestForSeason, QuizAlreadyFinished
|
||||
|
||||
|
||||
class QuestionView(View):
|
||||
class QuestionView(View, TemplateResponseMixin):
|
||||
template_name = "quiz/question.html"
|
||||
|
||||
def get(
|
||||
@@ -18,14 +20,26 @@ class QuestionView(View):
|
||||
try:
|
||||
question = candidate.get_next_question(candidate)
|
||||
except NoActiveTestForSeason:
|
||||
messages.error(request, _("No active Quiz for season"))
|
||||
raise Http404("No active Quiz for seaon")
|
||||
messages.error(request, _("No active quiz for season"))
|
||||
return redirect("home")
|
||||
except QuizAlreadyFinished:
|
||||
if not kwargs.get("from_post"):
|
||||
messages.error(request, _("Quiz done"))
|
||||
|
||||
return render(
|
||||
request,
|
||||
"quiz/question.html",
|
||||
{"candidate": candidate, "question": question},
|
||||
)
|
||||
return redirect(reverse("quiz", kwargs={"season": candidate.season}))
|
||||
|
||||
# TODO: On first question -> record time
|
||||
if (
|
||||
GivenAnswer.objects.filter(
|
||||
candidate=candidate, quiz=candidate.season.active_quiz
|
||||
).count()
|
||||
== 0
|
||||
):
|
||||
GivenAnswer.objects.create(
|
||||
candidate=candidate, quiz=question.quiz, answer=None
|
||||
)
|
||||
|
||||
return self.render_to_response({"candidate": candidate, "question": question})
|
||||
|
||||
def post(self, request: HttpRequest, candidate: Candidate, *args, **kwargs):
|
||||
answer_id = request.POST.get("answer")
|
||||
@@ -38,7 +52,8 @@ class QuestionView(View):
|
||||
raise BadRequest
|
||||
|
||||
GivenAnswer.objects.create(
|
||||
candidate=candidate, question=answer.question, answer=answer
|
||||
candidate=candidate,
|
||||
quiz=answer.question.quiz,
|
||||
answer=answer,
|
||||
)
|
||||
|
||||
return self.get(request, candidate, args, kwargs)
|
||||
return self.get(request, candidate, from_post=True)
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
from crispy_forms.helper import FormHelper
|
||||
from django import forms
|
||||
from django.contrib import messages
|
||||
from django.http import Http404
|
||||
from django.shortcuts import redirect
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext as _
|
||||
from django.views.generic.edit import FormView
|
||||
from django import forms
|
||||
from mypy.dmypy.client import request
|
||||
|
||||
from ..models import Season
|
||||
|
||||
@@ -24,6 +27,7 @@ class SelectSeasonView(FormView):
|
||||
try:
|
||||
season = Season.objects.get(season_code=form.cleaned_data["code"].upper())
|
||||
except Season.DoesNotExist:
|
||||
raise Http404("Season does not exist")
|
||||
messages.warning(self.request, _("Invalid season code"))
|
||||
return redirect("home")
|
||||
|
||||
return redirect(reverse("quiz", kwargs={"season": season}))
|
||||
|
||||
Reference in New Issue
Block a user