mirror of
https://github.com/MarijnDoeve/TijdVoorDeTest.git
synced 2026-03-06 04:44:19 +01:00
progress
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
|
.idea/
|
||||||
### Generated by gibo (https://github.com/simonwhitaker/gibo)
|
### Generated by gibo (https://github.com/simonwhitaker/gibo)
|
||||||
### https://raw.github.com/github/gitignore/76739a38b56907118c5a880d63250c99d5690a5a/Python.gitignore
|
### https://raw.github.com/github/gitignore/76739a38b56907118c5a880d63250c99d5690a5a/Python.gitignore
|
||||||
|
|
||||||
@@ -174,6 +175,7 @@ cython_debug/
|
|||||||
# Icon must end with two \r
|
# Icon must end with two \r
|
||||||
Icon
|
Icon
|
||||||
|
|
||||||
|
|
||||||
# Thumbnails
|
# Thumbnails
|
||||||
._*
|
._*
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ kunnen alleen vooraf ingevoerde namen gebruikt worden in een test.
|
|||||||
- Vanaf het moment dat de kandidaat op start klikt na het intypen van hun naam
|
- Vanaf het moment dat de kandidaat op start klikt na het intypen van hun naam
|
||||||
gaat de tijd lopen. Deze stopt na het aanklikken van een antwoord op de laatste
|
gaat de tijd lopen. Deze stopt na het aanklikken van een antwoord op de laatste
|
||||||
vraag van de test.
|
vraag van de test.
|
||||||
|
- Achtergrondmuziek
|
||||||
|
|
||||||
|
|
||||||
### Schermen kijken
|
### Schermen kijken
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-10-20 00:06+0200\n"
|
"POT-Creation-Date: 2024-11-24 12:18+0100\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@@ -18,10 +18,10 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
#: tvdt/settings.py:109
|
#: tvdt/settings.py:147
|
||||||
msgid "Dutch"
|
msgid "Dutch"
|
||||||
msgstr "Nederlands"
|
msgstr "Nederlands"
|
||||||
|
|
||||||
#: tvdt/settings.py:109
|
#: tvdt/settings.py:147
|
||||||
msgid "English"
|
msgid "English"
|
||||||
msgstr "Engels"
|
msgstr "Engels"
|
||||||
|
|||||||
20
tvdt/poetry.lock
generated
20
tvdt/poetry.lock
generated
@@ -101,24 +101,6 @@ django-crispy-forms = ">=2.3"
|
|||||||
[package.extras]
|
[package.extras]
|
||||||
test = ["pytest", "pytest-django"]
|
test = ["pytest", "pytest-django"]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "crispy-tailwind"
|
|
||||||
version = "1.0.3"
|
|
||||||
description = "Tailwind CSS for Django Crispy Forms"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.8"
|
|
||||||
files = [
|
|
||||||
{file = "crispy-tailwind-1.0.3.tar.gz", hash = "sha256:2bc9f616d406e4b003f25d46fcb0079f1c2522719d97adb107667271d849459a"},
|
|
||||||
{file = "crispy_tailwind-1.0.3-py3-none-any.whl", hash = "sha256:31427f66b1c4fd0d6fb040f4197cfb97d104cdbe7641ea2dea940c0057c4db4b"},
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
django = ">=4.2"
|
|
||||||
django-crispy-forms = ">=2.0"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
test = ["pytest", "pytest-django"]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "django"
|
name = "django"
|
||||||
version = "5.1.3"
|
version = "5.1.3"
|
||||||
@@ -379,4 +361,4 @@ files = [
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.12"
|
python-versions = "^3.12"
|
||||||
content-hash = "95199cfe52c42cc9e58c63f0f09684bff9a129c583fbbeb74e9c2ffa9c531813"
|
content-hash = "c7f81b41e492344223fddfa4c37985437e3f8d0012c90b968f9dd3fdd0c67833"
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ package-mode = false
|
|||||||
python = "^3.12"
|
python = "^3.12"
|
||||||
Django = "^5.1.2"
|
Django = "^5.1.2"
|
||||||
django-crispy-forms = "^2.3"
|
django-crispy-forms = "^2.3"
|
||||||
crispy-tailwind = "^1.0.3"
|
|
||||||
crispy-bootstrap5 = "^2024.10"
|
crispy-bootstrap5 = "^2024.10"
|
||||||
django-allauth = "^65.1.0"
|
django-allauth = "^65.1.0"
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from django.contrib import admin
|
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):
|
class CandidatesAdmin(admin.StackedInline):
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import base64
|
import base64
|
||||||
import binascii
|
import binascii
|
||||||
|
|
||||||
from .models import Season, Candidate
|
from .models import Candidate, Season
|
||||||
|
|
||||||
|
|
||||||
class SeasonCodeConverter:
|
class SeasonCodeConverter:
|
||||||
|
|||||||
@@ -1136,6 +1136,30 @@
|
|||||||
"name": "Tom"
|
"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",
|
"model": "quiz.quiz",
|
||||||
"pk": 1,
|
"pk": 1,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \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"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@@ -18,93 +18,77 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
#: quiz/models/answer.py:10
|
#: quiz/apps.py:8 quiz/models/correction.py:17 quiz/models/given_answer.py:19
|
||||||
msgid "text"
|
#: quiz/models/question.py:20 quiz/models/quiz.py:24
|
||||||
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
|
|
||||||
msgid "quiz"
|
msgid "quiz"
|
||||||
msgstr "test"
|
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"
|
msgid "correction"
|
||||||
msgstr "joker"
|
msgstr "joker"
|
||||||
|
|
||||||
#: quiz/models/correction.py:26
|
#: quiz/models/correction.py:23
|
||||||
msgid "corrections"
|
msgid "corrections"
|
||||||
msgstr "jokers"
|
msgstr "jokers"
|
||||||
|
|
||||||
#: quiz/models/given_answer.py:30
|
#: quiz/models/given_answer.py:36
|
||||||
msgid "given answer"
|
msgid "given answer"
|
||||||
msgstr "gegeven antwoord"
|
msgstr "gegeven antwoord"
|
||||||
|
|
||||||
#: quiz/models/given_answer.py:31
|
#: quiz/models/given_answer.py:37
|
||||||
msgid "given answers"
|
msgid "given answers"
|
||||||
msgstr "gegeven antwoorden"
|
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
|
#: quiz/models/question.py:22
|
||||||
|
msgid "enabled"
|
||||||
|
msgstr "actief"
|
||||||
|
|
||||||
|
#: quiz/models/question.py:29
|
||||||
msgid "questions"
|
msgid "questions"
|
||||||
msgstr "vraag"
|
msgstr "vraag"
|
||||||
|
|
||||||
#: quiz/models/quiz.py:14 quiz/models/season.py:38
|
#: quiz/models/quiz.py:12 quiz/models/season.py:38
|
||||||
msgid "season"
|
msgid "season"
|
||||||
msgstr "seizoen"
|
msgstr "seizoen"
|
||||||
|
|
||||||
#: quiz/models/quiz.py:27
|
#: quiz/models/quiz.py:25
|
||||||
msgid "quizzes"
|
msgid "quizzes"
|
||||||
msgstr "tests"
|
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
|
#: quiz/models/season.py:19
|
||||||
msgid "active quiz"
|
msgid "active quiz"
|
||||||
msgstr "actieve test"
|
msgstr "actieve test"
|
||||||
@@ -120,3 +104,35 @@ msgstr "kandidaten voorregistreren"
|
|||||||
#: quiz/models/season.py:39
|
#: quiz/models/season.py:39
|
||||||
msgid "seasons"
|
msgid "seasons"
|
||||||
msgstr "seizoenen"
|
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 django.db.models.deletion
|
||||||
import quiz.helpers
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
import quiz.helpers
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
@@ -24,7 +25,7 @@ class Migration(migrations.Migration):
|
|||||||
verbose_name="ID",
|
verbose_name="ID",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
("name", models.CharField(max_length=16, verbose_name="naam")),
|
("name", models.CharField(max_length=16, verbose_name="name")),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
"verbose_name": "candidate",
|
"verbose_name": "candidate",
|
||||||
@@ -44,7 +45,6 @@ class Migration(migrations.Migration):
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
("question", models.CharField(max_length=256, verbose_name="question")),
|
("question", models.CharField(max_length=256, verbose_name="question")),
|
||||||
("number", models.PositiveSmallIntegerField(verbose_name="number")),
|
|
||||||
("enabled", models.BooleanField(default=True, verbose_name="enabled")),
|
("enabled", models.BooleanField(default=True, verbose_name="enabled")),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
@@ -64,7 +64,7 @@ class Migration(migrations.Migration):
|
|||||||
verbose_name="ID",
|
verbose_name="ID",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
("name", models.CharField(max_length=64, verbose_name="naam")),
|
("name", models.CharField(max_length=64, verbose_name="name")),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
"verbose_name": "quiz",
|
"verbose_name": "quiz",
|
||||||
@@ -91,7 +91,7 @@ class Migration(migrations.Migration):
|
|||||||
(
|
(
|
||||||
"candidates",
|
"candidates",
|
||||||
models.ManyToManyField(
|
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={
|
options={
|
||||||
"verbose_name": "answer",
|
"verbose_name": "answer",
|
||||||
"verbose_name_plural": "answers",
|
"verbose_name_plural": "answers",
|
||||||
|
"order_with_respect_to": "question",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
@@ -120,7 +121,7 @@ class Migration(migrations.Migration):
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name="QuizTime",
|
name="GivenAnswer",
|
||||||
fields=[
|
fields=[
|
||||||
(
|
(
|
||||||
"id",
|
"id",
|
||||||
@@ -131,11 +132,21 @@ class Migration(migrations.Migration):
|
|||||||
verbose_name="ID",
|
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",
|
"candidate",
|
||||||
models.ForeignKey(
|
models.ForeignKey(
|
||||||
on_delete=django.db.models.deletion.CASCADE,
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="answers",
|
||||||
to="quiz.candidate",
|
to="quiz.candidate",
|
||||||
verbose_name="candidate",
|
verbose_name="candidate",
|
||||||
),
|
),
|
||||||
@@ -144,14 +155,16 @@ class Migration(migrations.Migration):
|
|||||||
"quiz",
|
"quiz",
|
||||||
models.ForeignKey(
|
models.ForeignKey(
|
||||||
on_delete=django.db.models.deletion.CASCADE,
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="+",
|
||||||
to="quiz.quiz",
|
to="quiz.quiz",
|
||||||
verbose_name="quiz",
|
verbose_name="quiz",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
"verbose_name": "quiz time",
|
"verbose_name": "given answer",
|
||||||
"verbose_name_plural": "quiz times",
|
"verbose_name_plural": "given answers",
|
||||||
|
"ordering": ("quiz", "candidate"),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
@@ -166,7 +179,7 @@ class Migration(migrations.Migration):
|
|||||||
verbose_name="ID",
|
verbose_name="ID",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
("name", models.CharField(max_length=64, verbose_name="naam")),
|
("name", models.CharField(max_length=64, verbose_name="name")),
|
||||||
(
|
(
|
||||||
"season_code",
|
"season_code",
|
||||||
models.CharField(
|
models.CharField(
|
||||||
@@ -175,9 +188,16 @@ class Migration(migrations.Migration):
|
|||||||
verbose_name="season code",
|
verbose_name="season code",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
"preregister_candidates",
|
||||||
|
models.BooleanField(
|
||||||
|
default=True, verbose_name="preregister candidates"
|
||||||
|
),
|
||||||
|
),
|
||||||
(
|
(
|
||||||
"active_quiz",
|
"active_quiz",
|
||||||
models.ForeignKey(
|
models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
default=None,
|
default=None,
|
||||||
null=True,
|
null=True,
|
||||||
on_delete=django.db.models.deletion.SET_NULL,
|
on_delete=django.db.models.deletion.SET_NULL,
|
||||||
@@ -212,54 +232,9 @@ class Migration(migrations.Migration):
|
|||||||
verbose_name="season",
|
verbose_name="season",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.AlterOrderWithRespectTo(
|
||||||
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(
|
|
||||||
name="question",
|
name="question",
|
||||||
unique_together={("quiz", "number")},
|
order_with_respect_to="quiz",
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name="Correction",
|
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 .given_answer import GivenAnswer
|
||||||
from .question import Question
|
from .question import Question
|
||||||
from .quiz import Quiz
|
from .quiz import Quiz
|
||||||
from .quiz_time import QuizTime
|
|
||||||
from .season import Season
|
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 django_stubs_ext.db.models import TypedModelMeta
|
||||||
|
|
||||||
from .given_answer import GivenAnswer
|
from .given_answer import GivenAnswer
|
||||||
from .question import NoActiveTestForSeason, QuizAlreadyFinished, Question
|
from .question import NoActiveTestForSeason, Question, QuizAlreadyFinished
|
||||||
|
|
||||||
|
|
||||||
class Candidate(models.Model):
|
class Candidate(models.Model):
|
||||||
@@ -23,11 +23,13 @@ class Candidate(models.Model):
|
|||||||
raise NoActiveTestForSeason()
|
raise NoActiveTestForSeason()
|
||||||
|
|
||||||
question = (
|
question = (
|
||||||
Question.objects.filter(quiz=quiz)
|
Question.objects.filter(quiz=quiz, enabled=True)
|
||||||
.exclude(
|
.exclude(
|
||||||
id__in=GivenAnswer.objects.filter(
|
id__in=GivenAnswer.objects.filter(
|
||||||
candidate=candidate, question__quiz=quiz
|
candidate=candidate,
|
||||||
).values_list("question_id", flat=True)
|
quiz=quiz,
|
||||||
|
answer__isnull=False,
|
||||||
|
).values_list("answer__question_id", flat=True)
|
||||||
)
|
)
|
||||||
.first()
|
.first()
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,9 +2,6 @@ from django.db import models
|
|||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django_stubs_ext.db.models import TypedModelMeta
|
from django_stubs_ext.db.models import TypedModelMeta
|
||||||
|
|
||||||
from .candidate import Candidate
|
|
||||||
from .quiz import Quiz
|
|
||||||
|
|
||||||
|
|
||||||
class Correction(models.Model):
|
class Correction(models.Model):
|
||||||
candidate = models.ForeignKey(
|
candidate = models.ForeignKey(
|
||||||
|
|||||||
@@ -10,20 +10,28 @@ class GivenAnswer(models.Model):
|
|||||||
related_name="answers",
|
related_name="answers",
|
||||||
verbose_name=_("candidate"),
|
verbose_name=_("candidate"),
|
||||||
)
|
)
|
||||||
question = models.ForeignKey(
|
|
||||||
"Question",
|
quiz = models.ForeignKey(
|
||||||
|
"Quiz",
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
null=True,
|
null=False,
|
||||||
related_name="given_answers",
|
related_name="+",
|
||||||
verbose_name=_("question"),
|
verbose_name=_("quiz"),
|
||||||
)
|
)
|
||||||
|
|
||||||
answer = models.ForeignKey(
|
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)
|
created = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.quiz} - {self.candidate.name} {self.answer}"
|
||||||
|
|
||||||
class Meta(TypedModelMeta):
|
class Meta(TypedModelMeta):
|
||||||
unique_together = ["candidate", "question"]
|
ordering = ("quiz", "candidate")
|
||||||
|
|
||||||
verbose_name = _("given answer")
|
verbose_name = _("given answer")
|
||||||
verbose_name_plural = _("given answers")
|
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 %}
|
{% load static %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en" data-bs-theme="dark">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
{# <script src="https://cdn.tailwindcss.com"></script>#}
|
{# <script src="https://cdn.tailwindcss.com"></script>#}
|
||||||
@@ -17,17 +17,33 @@
|
|||||||
background-position: center center;
|
background-position: center center;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-color: black;
|
background-color: black;
|
||||||
|
color: white;
|
||||||
|
|
||||||
display: grid;
|
display: grid;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-self: center;
|
justify-self: center;
|
||||||
color: white;
|
}
|
||||||
|
|
||||||
|
.asteriskField {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<main>
|
||||||
{% block body %}{% endblock %}
|
<div class="container">
|
||||||
</div>
|
{% if messages %}
|
||||||
{% block script %}{% endblock %}
|
{% 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>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
|
|
||||||
<p>{{ season.name }} ({{ season.season_code }})</p>
|
|
||||||
{% crispy form %}
|
{% crispy form %}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -2,8 +2,8 @@ from django.urls import path, register_converter
|
|||||||
|
|
||||||
from .converters import CandidateConverter, SeasonCodeConverter
|
from .converters import CandidateConverter, SeasonCodeConverter
|
||||||
from .views import SelectSeasonView
|
from .views import SelectSeasonView
|
||||||
from .views.questionview import QuestionView
|
|
||||||
from .views.enternameview import EnterNameView
|
from .views.enternameview import EnterNameView
|
||||||
|
from .views.questionview import QuestionView
|
||||||
|
|
||||||
register_converter(SeasonCodeConverter, "season")
|
register_converter(SeasonCodeConverter, "season")
|
||||||
register_converter(CandidateConverter, "candidate")
|
register_converter(CandidateConverter, "candidate")
|
||||||
|
|||||||
@@ -1,47 +1,47 @@
|
|||||||
from crispy_forms.helper import FormHelper
|
from crispy_forms.helper import FormHelper
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.http import Http404
|
from django.contrib import messages
|
||||||
from django.shortcuts import render, redirect
|
from django.shortcuts import redirect
|
||||||
from django.urls import reverse
|
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 import View
|
||||||
|
from django.views.generic.base import TemplateResponseMixin
|
||||||
|
|
||||||
from ..models import Season, Candidate
|
from ..models import Candidate, Season
|
||||||
|
|
||||||
|
|
||||||
class EnterNameForm(forms.Form):
|
class EnterNameForm(forms.Form):
|
||||||
name = forms.CharField()
|
name = forms.CharField(label=_("Name"))
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.helper = FormHelper()
|
self.helper = FormHelper()
|
||||||
|
|
||||||
|
|
||||||
class EnterNameView(View):
|
class EnterNameView(View, TemplateResponseMixin):
|
||||||
template_name = "quiz/enter_name.html"
|
template_name = "quiz/enter_name.html"
|
||||||
forms_class = EnterNameForm
|
forms_class = EnterNameForm
|
||||||
|
|
||||||
def get(self, request, season: Season, *args, **kwargs):
|
def get(self, request, season: Season, *args, **kwargs):
|
||||||
if season.active_quiz == None:
|
if season.active_quiz == None:
|
||||||
raise Http404("No quiz active")
|
messages.info(request, _("This season has no active quiz."))
|
||||||
|
return redirect("home")
|
||||||
|
|
||||||
return render(
|
return self.render_to_response({"form": self.forms_class()})
|
||||||
request,
|
|
||||||
self.template_name,
|
|
||||||
{"form": self.forms_class(), "season": season},
|
|
||||||
)
|
|
||||||
|
|
||||||
def post(self, request, season: Season, *args, **kwargs):
|
def post(self, request, season: Season, *args, **kwargs):
|
||||||
name = request.POST.get("name")
|
name = request.POST.get("name")
|
||||||
|
|
||||||
if season.preregister_candidates:
|
|
||||||
try:
|
try:
|
||||||
candidate = Candidate.objects.get(season=season, name=name)
|
candidate = Candidate.objects.get(season=season, name__iexact=name)
|
||||||
except Candidate.DoesNotExist:
|
except Candidate.DoesNotExist:
|
||||||
raise Http404("Candidate not found")
|
if season.preregister_candidates:
|
||||||
else:
|
messages.warning(request, _("Candidate does not exist"))
|
||||||
candidate, created = Candidate.objects.get_or_create(
|
|
||||||
season=season, name=name
|
return redirect(reverse("quiz", kwargs={"season": season}))
|
||||||
)
|
|
||||||
|
candidate = Candidate.objects.create(season=season, name=name)
|
||||||
|
|
||||||
return redirect(
|
return redirect(
|
||||||
reverse(
|
reverse(
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.core.exceptions import BadRequest
|
from django.core.exceptions import BadRequest
|
||||||
from django.http import Http404, HttpRequest, HttpResponse
|
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.utils.translation import gettext as _
|
||||||
from django.views import View
|
from django.views import View
|
||||||
|
from django.views.generic.base import TemplateResponseMixin
|
||||||
|
|
||||||
from ..models import Candidate, Answer, GivenAnswer
|
from ..models import Answer, Candidate, GivenAnswer
|
||||||
from ..models.question import NoActiveTestForSeason
|
from ..models.question import NoActiveTestForSeason, QuizAlreadyFinished
|
||||||
|
|
||||||
|
|
||||||
class QuestionView(View):
|
class QuestionView(View, TemplateResponseMixin):
|
||||||
template_name = "quiz/question.html"
|
template_name = "quiz/question.html"
|
||||||
|
|
||||||
def get(
|
def get(
|
||||||
@@ -18,15 +20,27 @@ class QuestionView(View):
|
|||||||
try:
|
try:
|
||||||
question = candidate.get_next_question(candidate)
|
question = candidate.get_next_question(candidate)
|
||||||
except NoActiveTestForSeason:
|
except NoActiveTestForSeason:
|
||||||
messages.error(request, _("No active Quiz for season"))
|
messages.error(request, _("No active quiz for season"))
|
||||||
raise Http404("No active Quiz for seaon")
|
return redirect("home")
|
||||||
|
except QuizAlreadyFinished:
|
||||||
|
if not kwargs.get("from_post"):
|
||||||
|
messages.error(request, _("Quiz done"))
|
||||||
|
|
||||||
return render(
|
return redirect(reverse("quiz", kwargs={"season": candidate.season}))
|
||||||
request,
|
|
||||||
"quiz/question.html",
|
# TODO: On first question -> record time
|
||||||
{"candidate": candidate, "question": question},
|
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):
|
def post(self, request: HttpRequest, candidate: Candidate, *args, **kwargs):
|
||||||
answer_id = request.POST.get("answer")
|
answer_id = request.POST.get("answer")
|
||||||
if answer_id == None:
|
if answer_id == None:
|
||||||
@@ -38,7 +52,8 @@ class QuestionView(View):
|
|||||||
raise BadRequest
|
raise BadRequest
|
||||||
|
|
||||||
GivenAnswer.objects.create(
|
GivenAnswer.objects.create(
|
||||||
candidate=candidate, question=answer.question, answer=answer
|
candidate=candidate,
|
||||||
|
quiz=answer.question.quiz,
|
||||||
|
answer=answer,
|
||||||
)
|
)
|
||||||
|
return self.get(request, candidate, from_post=True)
|
||||||
return self.get(request, candidate, args, kwargs)
|
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
from crispy_forms.helper import FormHelper
|
from crispy_forms.helper import FormHelper
|
||||||
|
from django import forms
|
||||||
|
from django.contrib import messages
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
from django.views.generic.edit import FormView
|
from django.views.generic.edit import FormView
|
||||||
from django import forms
|
from mypy.dmypy.client import request
|
||||||
|
|
||||||
from ..models import Season
|
from ..models import Season
|
||||||
|
|
||||||
@@ -24,6 +27,7 @@ class SelectSeasonView(FormView):
|
|||||||
try:
|
try:
|
||||||
season = Season.objects.get(season_code=form.cleaned_data["code"].upper())
|
season = Season.objects.get(season_code=form.cleaned_data["code"].upper())
|
||||||
except Season.DoesNotExist:
|
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}))
|
return redirect(reverse("quiz", kwargs={"season": season}))
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ https://docs.djangoproject.com/en/5.1/ref/settings/
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
from django.contrib import messages
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
@@ -125,6 +127,18 @@ AUTH_PASSWORD_VALIDATORS = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
MESSAGE_TAGS = {
|
||||||
|
messages.DEBUG: "alert-info",
|
||||||
|
messages.INFO: "alert-info",
|
||||||
|
messages.SUCCESS: "alert-success",
|
||||||
|
messages.WARNING: "alert-warning",
|
||||||
|
messages.ERROR: "alert-danger",
|
||||||
|
100: "alert-primary",
|
||||||
|
110: "alert-secondary",
|
||||||
|
120: "alert-light",
|
||||||
|
130: "alert-dark",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# Internationalization
|
# Internationalization
|
||||||
# https://docs.djangoproject.com/en/5.1/topics/i18n/
|
# https://docs.djangoproject.com/en/5.1/topics/i18n/
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ Including another URLconf
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.conf.urls.static import static
|
from django.conf.urls.static import static
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import path, include
|
from django.urls import include, path
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", include("quiz.urls")),
|
path("", include("quiz.urls")),
|
||||||
|
|||||||
Reference in New Issue
Block a user