Django 2.2.
[koed-quiz.git] / apps / quiz / models.py
1 # This file is part of KOED-Quiz, licensed under GNU Affero GPLv3 or later.
2 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
3 #
4 from django.db import models
5 from django.contrib.sites.models import Site
6 from django.urls import reverse
7 from django.utils.translation import ugettext_lazy as _
8
9 from django.conf import settings
10
11
12 class Quiz(Site):
13     description = models.TextField()
14     footer = models.TextField(null=True, blank=True)
15
16     class Meta:
17         verbose_name = _('quiz')
18         verbose_name_plural = _('quizzes')
19
20     @classmethod
21     def current(cls, request):
22         try:
23             return cls.objects.get(domain=request.get_host().rstrip('.'))
24         except cls.DoesNotExist:
25             pass
26
27     def start(self):
28         return self.question_set.all()[0]
29
30     def get_absolute_url(self):
31         return reverse('quiz')
32
33     def where_to(self):
34         try:
35             return Result.objects.get(quiz=self).get_absolute_url()
36         except Result.DoesNotExist:
37             # just go to the beginning
38             return self.get_absolute_url()
39
40
41 class Result(models.Model):
42     quiz = models.ForeignKey(Quiz, models.CASCADE)
43     slug = models.SlugField(db_index=True)
44     title = models.CharField(max_length=255)
45     text = models.TextField()
46
47     class Meta:
48         verbose_name = _('result')
49         verbose_name_plural = _('results')
50         ordering = ['quiz', 'title']
51
52     def __str__(self):
53         return self.title
54
55     def get_absolute_url(self):
56         return reverse('quiz_result', args=[self.slug])
57
58
59 class Question(models.Model):
60     quiz = models.ForeignKey(Quiz, models.CASCADE)
61     slug = models.SlugField(db_index=True)
62     ordering = models.SmallIntegerField()
63     title = models.CharField(max_length=255)
64     text = models.TextField(null=True, blank=True)
65     description = models.TextField(null=True, blank=True)
66
67     class Meta:
68         verbose_name = _('question')
69         verbose_name_plural = _('questions')
70         ordering = ['quiz', 'ordering']
71         unique_together = [['quiz', 'slug'], ['quiz', 'ordering']]
72
73     def __str__(self):
74         return self.title
75
76     def get_absolute_url(self):
77         return reverse('quiz', args=[self.slug])
78
79     def where_to(self):
80         later = self.quiz.question_set.filter(ordering__gt=self.ordering)
81         if later.exists():
82             return later[0].get_absolute_url()
83         else:
84             return self.quiz.where_to()
85
86
87 class Answer(models.Model):
88     title = models.CharField(max_length=255)
89     question = models.ForeignKey(Question, models.CASCADE)
90     go_to = models.ForeignKey(Question, models.SET_NULL, null=True, blank=True,
91             related_name='go_tos')
92     result = models.ForeignKey(Result, models.SET_NULL, null=True, blank=True)
93     ordering = models.SmallIntegerField()
94
95     class Meta:
96         verbose_name = _('answer')
97         verbose_name_plural = _('answers')
98         ordering = ['question', 'ordering']
99
100     def __str__(self):
101         return self.title
102
103     def where_to(self):
104         # follow explicit redirects
105         if self.result:
106             return self.result.get_absolute_url()
107         elif self.go_to:
108             return self.go_to.get_absolute_url()
109
110         # or just get the next question
111         return self.question.where_to()