diff --git a/unisportomat/quiz/management/commands/seed_db.py b/unisportomat/quiz/management/commands/seed_db.py index 9bfe4e7eb5098a4dd9a8fb3f748c5b9457c7515d..4413c59fbc77655386f9ed4da1e08fe6cae13139 100644 --- a/unisportomat/quiz/management/commands/seed_db.py +++ b/unisportomat/quiz/management/commands/seed_db.py @@ -74,7 +74,7 @@ class Command(BaseCommand): "Bouldern", ] for name in sports_names: - Sport(name=name).save() + Sport.objects.create_sport(name=name).save() # Create criteria criteria_names = [ @@ -85,7 +85,7 @@ class Command(BaseCommand): "Kampfsport", ] for name in criteria_names: - Criterion(name=name).save() + Criterion.objects.create_criterion(name=name).save() # Create ratings for all sports and criterions for sport in Sport.objects.all(): diff --git a/unisportomat/quiz/models.py b/unisportomat/quiz/models.py index d582994f73b3de31d04f59e1a1e8d16539cf3ed8..d64e9056d0203d800eeb85875094ad329c7a566f 100644 --- a/unisportomat/quiz/models.py +++ b/unisportomat/quiz/models.py @@ -1,9 +1,20 @@ """ Model definitions for the quiz """ from django.core.validators import MaxValueValidator, MinValueValidator +from django.core.exceptions import ValidationError from django.db import models +def validate_rating(value): + """ + TODO: Validations are only run when using Model Forms. + """ + + print("Validating") + if not (value <= 10 or value >= 1 or value == -1): + raise ValidationError(u"%s is not a valid rating!" % value) + + class CriterionRating(models.Model): """ This is the relation between Sport and Criterion. @@ -11,9 +22,7 @@ class CriterionRating(models.Model): To see it's usage check Sport.rate() and Sport.get_rating() """ - rating = models.IntegerField( - validators=[MaxValueValidator(10), MinValueValidator(1)] - ) + rating = models.IntegerField(validators=[validate_rating]) criterion = models.ForeignKey("Criterion", on_delete=models.CASCADE) sport = models.ForeignKey("Sport", on_delete=models.CASCADE) @@ -21,6 +30,25 @@ class CriterionRating(models.Model): return str(self.sport) + " - " + str(self.criterion) + ": " + str(self.rating) +class SportManager(models.Manager): + """ + Manages Creation of Sport Objects + Since every Criterion Connection needs to be present in the DB at all times, + the connections are made at creation of the Sport object. For this, Sport objects need to be + created through this Manager Class. + + Docs: https://docs.djangoproject.com/en/3.2/ref/models/instances/#creating-objects + """ + + def create_sport(self, **kwargs): + sport = self.create(**kwargs) + + for crit in Criterion.objects.iterator(): + sport.rate(crit, -1) + + return sport + + class Sport(models.Model): """ Defines a Sport with name, url that leads to the booking page. @@ -32,6 +60,8 @@ class Sport(models.Model): url = models.URLField() criteria_ratings = models.ManyToManyField("Criterion", through="CriterionRating") + objects = SportManager() + def __str__(self): return self.name @@ -50,6 +80,28 @@ class Sport(models.Model): return criterion_rating.rating +class CriterionManager(models.Manager): + """ + Manages Creation of Criterion Objects + Since every Sport Object needs to be rated in every criterion, + when a new Criterion is created, every Sport object needs to be rated for that Criterion. + As a default Value, -1 is entered so that it can be recognized that no true value is given. + + Docs: https://docs.djangoproject.com/en/3.2/ref/models/instances/#creating-objects + """ + + def create_criterion(self, **kwargs): + crit = Criterion(**kwargs) + + # Criterion needs to be saved before it can be connected to a sport + crit.save() + + for sport in Sport.objects.iterator(): + sport.rate(crit, -1) + + return crit + + class Criterion(models.Model): """ Defines a Sport property that is used a a criterion for our quiz. @@ -58,6 +110,8 @@ class Criterion(models.Model): name = models.TextField() + objects = CriterionManager() + def __str__(self): return self.name diff --git a/unisportomat/quiz/views.py b/unisportomat/quiz/views.py index 8e8bfb6a24d65b50adacbe860e24893255b0b1ab..f36d5f5f9753799bf1363f7a76c9b1f0b03b47c3 100644 --- a/unisportomat/quiz/views.py +++ b/unisportomat/quiz/views.py @@ -121,7 +121,7 @@ class SmallSportListView(viewsets.ViewSet): print(data_dict) - new_sport = Sport() + new_sport = Sport.objects.create_sport() new_sport.name = data_dict["name"] new_sport.url = data_dict["url"]