""" Model definitions for the quiz """ from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models class CriterionRating(models.Model): """ This is the relation between Sport and Criterion. You can use it to add a rating for a specific criterion to a sport. To see it's usage check Sport.rate() and Sport.get_rating() """ rating = models.IntegerField( validators=[MaxValueValidator(10), MinValueValidator(1)] ) criterion = models.ForeignKey("Criterion", on_delete=models.CASCADE) sport = models.ForeignKey("Sport", on_delete=models.CASCADE) def __str__(self): return str(self.sport) + " - " + str(self.criterion) + ": " + str(self.rating) class Sport(models.Model): """ Defines a Sport with name, url that leads to the booking page. A sport includes ratings for all criterions. (e.g. How much it corresponds to the criterion "Martial Arts") """ name = models.TextField() url = models.URLField() criteria_ratings = models.ManyToManyField("Criterion", through="CriterionRating") def __str__(self): return self.name def rate(self, criterion, rating): """Defines how much (rating) the sport meets the given criterion""" rating_obj, _ = CriterionRating.objects.get_or_create( sport=self, criterion=criterion, defaults={"rating": rating} ) rating_obj.rating = rating rating_obj.save() return rating_obj def get_rating(self, criterion): """Returns how much the sport meets the given criterion""" criterion_rating = CriterionRating.objects.get(sport=self, criterion=criterion) return criterion_rating.rating class Criterion(models.Model): """ Defines a Sport property that is used a a criterion for our quiz. (e.g. Individual or Team sport) """ name = models.TextField() def __str__(self): return self.name class CallToMove(models.Model): """Defines text and image that are used to show a call to move between questions""" text = models.TextField() image = models.ImageField(null=True, max_length=200) def __str__(self): return self.text class KnowledgeSnack(models.Model): """Defines text and image that are used to show a KnowledgeSnack between questions""" text = models.TextField() image = models.ImageField(null=True, max_length=200) def __str__(self): return self.text class Question(models.Model): """Defines a Question that is assigned to exactly one Criterion""" text = models.TextField() criterion = models.OneToOneField( Criterion, on_delete=models.CASCADE, primary_key=True ) def __str__(self): return self.text