diff --git a/unisportomat/quiz/migrations/0007_auto_20210626_1130.py b/unisportomat/quiz/migrations/0007_auto_20210626_1130.py new file mode 100644 index 0000000000000000000000000000000000000000..d9c59dfc3dd3e02c0a93db350c2bb9012efaa96a --- /dev/null +++ b/unisportomat/quiz/migrations/0007_auto_20210626_1130.py @@ -0,0 +1,30 @@ +# Generated by Django 3.2 on 2021-06-26 11:30 + +import datetime +from django.db import migrations, models +import quiz.models + + +class Migration(migrations.Migration): + + dependencies = [ + ("quiz", "0006_auto_20210612_1230"), + ] + + operations = [ + migrations.AddField( + model_name="sport", + name="currently_active", + field=models.BooleanField(default=True), + ), + migrations.AddField( + model_name="sport", + name="last_used", + field=models.DateField(default=datetime.date(2021, 6, 26)), + ), + migrations.AlterField( + model_name="criterionrating", + name="rating", + field=models.IntegerField(validators=[quiz.models.validate_rating]), + ), + ] diff --git a/unisportomat/quiz/migrations/0008_alter_sport_last_used.py b/unisportomat/quiz/migrations/0008_alter_sport_last_used.py new file mode 100644 index 0000000000000000000000000000000000000000..5a5e06b96d2149901c63a005ff9e5a1c72e2e64e --- /dev/null +++ b/unisportomat/quiz/migrations/0008_alter_sport_last_used.py @@ -0,0 +1,22 @@ +# Generated by Django 3.2 on 2021-06-26 11:32 + +import datetime +from django.db import migrations, models +from django.utils.timezone import utc + + +class Migration(migrations.Migration): + + dependencies = [ + ("quiz", "0007_auto_20210626_1130"), + ] + + operations = [ + migrations.AlterField( + model_name="sport", + name="last_used", + field=models.DateField( + default=datetime.datetime(2021, 6, 26, 11, 32, 52, 231135, tzinfo=utc) + ), + ), + ] diff --git a/unisportomat/quiz/migrations/0009_alter_sport_last_used.py b/unisportomat/quiz/migrations/0009_alter_sport_last_used.py new file mode 100644 index 0000000000000000000000000000000000000000..fdff24a74c6ede72aded2b24ca5c01f2a4973231 --- /dev/null +++ b/unisportomat/quiz/migrations/0009_alter_sport_last_used.py @@ -0,0 +1,22 @@ +# Generated by Django 3.2 on 2021-06-26 11:33 + +import datetime +from django.db import migrations, models +from django.utils.timezone import utc + + +class Migration(migrations.Migration): + + dependencies = [ + ("quiz", "0008_alter_sport_last_used"), + ] + + operations = [ + migrations.AlterField( + model_name="sport", + name="last_used", + field=models.DateField( + default=datetime.datetime(2021, 6, 26, 11, 33, 26, 967602, tzinfo=utc) + ), + ), + ] diff --git a/unisportomat/quiz/migrations/0010_alter_sport_last_used.py b/unisportomat/quiz/migrations/0010_alter_sport_last_used.py new file mode 100644 index 0000000000000000000000000000000000000000..cf01355db7f84777abbb3babee4c85baa4ad77e6 --- /dev/null +++ b/unisportomat/quiz/migrations/0010_alter_sport_last_used.py @@ -0,0 +1,22 @@ +# Generated by Django 3.2 on 2021-06-26 11:39 + +import datetime +from django.db import migrations, models +from django.utils.timezone import utc + + +class Migration(migrations.Migration): + + dependencies = [ + ("quiz", "0009_alter_sport_last_used"), + ] + + operations = [ + migrations.AlterField( + model_name="sport", + name="last_used", + field=models.DateTimeField( + default=datetime.datetime(2021, 6, 26, 11, 39, 12, 106108, tzinfo=utc) + ), + ), + ] diff --git a/unisportomat/quiz/migrations/0011_alter_sport_last_used.py b/unisportomat/quiz/migrations/0011_alter_sport_last_used.py new file mode 100644 index 0000000000000000000000000000000000000000..798a23521e313425f1f3b2ea274e5c976bde3d5b --- /dev/null +++ b/unisportomat/quiz/migrations/0011_alter_sport_last_used.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2 on 2021-06-26 11:39 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ("quiz", "0010_alter_sport_last_used"), + ] + + operations = [ + migrations.AlterField( + model_name="sport", + name="last_used", + field=models.DateField(default=django.utils.timezone.now), + ), + ] diff --git a/unisportomat/quiz/models.py b/unisportomat/quiz/models.py index 9a7b5b18510fdc173a512afbf3959659ca51319b..3605542fb7778f11508b0252a2c5e4c9642d8273 100644 --- a/unisportomat/quiz/models.py +++ b/unisportomat/quiz/models.py @@ -2,6 +2,7 @@ from django.core.exceptions import ValidationError from django.db import models +from django.utils import timezone def validate_rating(value): @@ -44,6 +45,8 @@ class SportManager(models.Manager): Creates new Sport Object and every CriterionRating for it """ sport = self.create(**kwargs) + sport.currently_active = True + sport.last_used = timezone.localdate() for crit in Criterion.objects.iterator(): sport.rate(crit, -1) @@ -62,6 +65,13 @@ class Sport(models.Model): url = models.URLField() criteria_ratings = models.ManyToManyField("Criterion", through="CriterionRating") + # The Date Field last_used is set to now-time everytime a sport is activated + # either through manual activation or activation through the scraper + last_used = models.DateField(default=timezone.localdate) + + # Boolean currently_active states whether the sport is in the archive or not + currently_active = models.BooleanField(default=True) + objects = SportManager() def __str__(self): @@ -93,6 +103,13 @@ class Sport(models.Model): return True + def reactivate(self): + """ + Sets currently_active to True and updates the last_used Date + """ + self.currently_active = True + self.last_used = timezone.localdate() + class CriterionManager(models.Manager): """ diff --git a/unisportomat/quiz/serializers.py b/unisportomat/quiz/serializers.py index 9756a8e190171e12071bfbd365b05c6dc05813f3..11d0e3a52049e9691c895d6bde03de731c54f967 100644 --- a/unisportomat/quiz/serializers.py +++ b/unisportomat/quiz/serializers.py @@ -76,6 +76,8 @@ class SingleSportSerializer(serializers.BaseSerializer): serialized_data["id"] = sport.pk serialized_data["name"] = sport.name serialized_data["url"] = sport.url + serialized_data["currently_active"] = sport.currently_active + serialized_data["last_used"] = sport.last_used criteria = [] @@ -113,6 +115,9 @@ class SingleSportSerializer(serializers.BaseSerializer): if "url" in request.data.keys(): sport_dictionary["url"] = request.data["url"] + if "currently_active" in request.data.keys(): + sport_dictionary["currently_active"] = request.data["currently_active"] + # If the Sport is only now created with a POST-Request, no Criteria can be filled out for it # This is because the Admin Frontend doesn't have a list of Criteria ready if "criteria" in request.data.keys(): diff --git a/unisportomat/quiz/tests.py b/unisportomat/quiz/tests.py index 80149025adbcb2b810b96ea4226dc47158511346..5d1f8c31c157831cd19abd621eaa3fb647c37fef 100644 --- a/unisportomat/quiz/tests.py +++ b/unisportomat/quiz/tests.py @@ -7,6 +7,7 @@ import tempfile from django.core.files.uploadedfile import SimpleUploadedFile from django.core.management import call_command from django.utils.translation import get_language, activate +from django.utils import timezone from django.urls import reverse from django.test import TestCase, override_settings from rest_framework.test import APITestCase @@ -400,6 +401,8 @@ class APITest(APITestCase): "id": 1, "name": "Jiu Jitsu", "url": "http://www.test.de", + "currently_active": True, + "last_used": timezone.localdate(), "criteria": [{"id": 1, "name": "Outdoorsport", "value": 1}], } self.assertDictEqual(response.data, sport_data) @@ -411,6 +414,7 @@ class APITest(APITestCase): sport_data = { "name": "Karate", "url": "http://www.test2.de", + "currently_active": True, "criteria": [{"id": 1, "name": "Outdoorsport", "value": 1}], } @@ -419,8 +423,12 @@ class APITest(APITestCase): data=sport_data, format="json", ) + + response = self.client.get(reverse("small-sport-list-detail", kwargs={"pk": 1})) + self.assertEqual(response.data["name"], sport_data["name"]) self.assertEqual(response.data["url"], sport_data["url"]) + self.assertEqual(response.data["currently_active"], True) self.assertEqual(len(response.data["criteria"]), Criterion.objects.count()) self.assertDictEqual( response.data["criteria"][0], {"id": 1, "name": "Outdoorsport", "value": 1} @@ -439,6 +447,9 @@ class APITest(APITestCase): data=sport_data, format="json", ) + + response = self.client.get(reverse("small-sport-list-detail", kwargs={"pk": 1})) + self.assertEqual(response.data["name"], "Jiu Jitsu") self.assertEqual(response.data["url"], "http://www.test.de") self.assertEqual(len(response.data["criteria"]), Criterion.objects.count()) @@ -520,3 +531,19 @@ class APITest(APITestCase): self.assertEqual(len(response.data), Criterion.objects.count()) self.assertEqual(response.data[0]["number_of_sports_active"], 1) self.assertEqual(response.data[0]["sum_of_weights"], 7) + + def test_currently_active(self): + """ + Tests if PATCHing the "currently_active" value to false correctly changes the sport + """ + + # Set Up Values + response = self.client.patch( + reverse("small-sport-list-detail", kwargs={"pk": 1}), + data={"currently_active": False}, + format="json", + ) + + response = self.client.get(reverse("small-sport-list-detail", kwargs={"pk": 1})) + + self.assertEqual(response.data["currently_active"], False) diff --git a/unisportomat/quiz/views.py b/unisportomat/quiz/views.py index 8d7e0cf870f1e7abe163f32f9f1b45b1dde0a76a..f2cf26e015a1212903b954ac57e479224db34ad5 100644 --- a/unisportomat/quiz/views.py +++ b/unisportomat/quiz/views.py @@ -75,7 +75,7 @@ class SmallSportListView(viewsets.ViewSet): paginator = PageNumberWithPageSizePagination() - sports = Sport.objects.all().order_by("name") + sports = Sport.objects.filter(currently_active=True).order_by("name") sports = paginator.paginate_queryset(sports, request) is_filled_tuples = [] @@ -146,10 +146,18 @@ class SmallSportListView(viewsets.ViewSet): sport.name = request_data["name"] sport.url = request_data["url"] + if request_data["currently_active"] is True and sport.currently_active is False: + # If the Sport is just now being activated, update the Date + sport.reactivate() + else: + sport.currently_active = request_data["currently_active"] + # Overwrite Criterion Ratings for criterion, value in request_data["criteria"]: sport.rate(criterion, value) + sport.save() + # Re-Serialize changed Sport and Send it back response = SingleSportSerializer(sport) @@ -179,9 +187,22 @@ class SmallSportListView(viewsets.ViewSet): if "url" in request_data.keys(): sport.url = request_data["url"] + if "currently_active" in request_data.keys(): + if ( + request_data["currently_active"] is True + and sport.currently_active is False + ): + # If the Sport is just now being activated, update the Date + sport.reactivate() + else: + sport.currently_active = request_data["currently_active"] + # Overwrite Criterion Ratings - for criterion, value in request_data["criteria"]: - sport.rate(criterion, value) + if "criteria" in request_data.keys(): + for criterion, value in request_data["criteria"]: + sport.rate(criterion, value) + + sport.save() # Re-Serialize changed Sport and Send it back response = SingleSportSerializer(sport) @@ -222,7 +243,7 @@ class IncompleteSportView(APIView): incomplete_sport_list = [] - for sport in queryset: + for sport in Sport.objects.filter(currently_active=True).iterator(): if not sport.is_filled(): incomplete_sport_list.append(sport)