diff --git a/competition/models.py b/competition/models.py index f3bbab87..e4984d43 100644 --- a/competition/models.py +++ b/competition/models.py @@ -150,7 +150,7 @@ class Meta: start = models.DateTimeField(verbose_name='dátum začiatku súťaže') end = models.DateTimeField(verbose_name='dátum konca súťaže') additional_name = models.CharField( - max_length=50, verbose_name='Prísvlastok súťaže', null=True, blank=True) + max_length=50, verbose_name='Prívlastok súťaže', null=True, blank=True) objects = ActiveQuerySet.as_manager() @@ -204,6 +204,11 @@ class Meta: blank=True, default=None) + def save(self, *args, **kwargs) -> None: + if not self.frozen_results: + self.frozen_results = None + return super().save(*args, **kwargs) + def get_first_series(self): return self.series_set.get(order=1) @@ -251,6 +256,11 @@ class Meta: blank=True, default=None) + def save(self, *args, **kwargs) -> None: + if not self.frozen_results: + self.frozen_results = None + return super().save(*args, **kwargs) + def __str__(self): return f'{self.semester} - {self.order}. séria' @@ -415,6 +425,11 @@ class Meta: hidden_response = models.TextField( null=True, blank=True, verbose_name='Skrytá odpoveď na komentár') + def save(self, *args, **kwargs) -> None: + if not self.hidden_response: + self.hidden_response = None + return super().save(*args, **kwargs) + def publish(self): self.state = CommentPublishState.PUBLISHED self.hidden_response = None diff --git a/competition/serializers.py b/competition/serializers.py index 70151eb7..9f37b0bc 100644 --- a/competition/serializers.py +++ b/competition/serializers.py @@ -60,7 +60,7 @@ class Meta: @ts_interface(context='competition') class CompetitionSerializer(serializers.ModelSerializer): - competition_type = CompetitionTypeSerializer(many=False) + competition_type = CompetitionTypeSerializer(many=False, read_only=True) upcoming_or_current_event = serializers.SerializerMethodField( 'get_upcoming_or_current') history_events = serializers.SerializerMethodField('get_history_events') diff --git a/competition/tests.py b/competition/tests.py index 023281ff..4df28c50 100644 --- a/competition/tests.py +++ b/competition/tests.py @@ -316,11 +316,11 @@ def test_get_competition_list(self): def test_get_competition_detail(self): '''detail format OK''' - response = self.client.get(self.URL_PREFIX + '/strom', {}, 'json') + response = self.client.get(self.URL_PREFIX + '/slug/strom', {}, 'json') self.assertEqual(response.status_code, 200) self.competition_assert_format(response.json(), 0) - response = self.client.get(self.URL_PREFIX + '/matik', {}, 'json') + response = self.client.get(self.URL_PREFIX + '/slug/matik', {}, 'json') self.assertEqual(response.status_code, 200) self.competition_assert_format(response.json(), 1) @@ -331,13 +331,25 @@ def test_permission_list(self): def test_permission_get(self): '''retrieve permission OK''' - self.check_permissions(self.URL_PREFIX + '/strom/', + self.check_permissions(self.URL_PREFIX + '/slug/strom/', 'GET', self.PUBLIC_OK_RESPONSES) def test_permission_update(self): ''' update permission OK''' - self.check_permissions(self.URL_PREFIX + '/strom/', 'PUT', - self.ALL_FORBIDDEN, {'start_year': 2020}) + self.check_permissions(self.URL_PREFIX + '/0/', 'PUT', + self.ONLY_STROM_OK_RESPONSES, + { + "id": 0, + "name": "STROM", + "slug": "strom", + "start_year": 1976, + "description": "popis", + "rules": "# Pravidlá", + "min_years_until_graduation": 0, + "sites": [ + 0 + ] + }) def test_permission_create(self): ''' create permission OK''' diff --git a/competition/views.py b/competition/views.py index c45d0d9f..fd88360f 100644 --- a/competition/views.py +++ b/competition/views.py @@ -12,6 +12,7 @@ from rest_framework.decorators import action from rest_framework.exceptions import ValidationError from rest_framework.permissions import IsAdminUser, IsAuthenticated +from rest_framework.request import Request from rest_framework.response import Response from base.utils import mime_type @@ -100,13 +101,22 @@ def generate_result_row( } -class CompetitionViewSet(viewsets.ReadOnlyModelViewSet): +class CompetitionViewSet(mixins.RetrieveModelMixin, + mixins.UpdateModelMixin, + mixins.ListModelMixin, + viewsets.GenericViewSet): """Naše aktivity""" queryset = Competition.objects.all() serializer_class = CompetitionSerializer - lookup_field = 'slug' permission_classes = (CompetitionRestrictedPermission,) + @action(detail=False, url_path=r'slug/(?P\w+)') + def slug(self, request: Request, slug: str = None) -> Response: + competition: Competition = self.get_queryset().get(slug=slug) + return Response( + CompetitionSerializer(competition, many=False).data + ) + class CommentViewSet( mixins.RetrieveModelMixin, diff --git a/personal/views.py b/personal/views.py index cf030313..61dc107c 100644 --- a/personal/views.py +++ b/personal/views.py @@ -1,5 +1,5 @@ from django_filters.rest_framework import DjangoFilterBackend -from rest_framework import status, viewsets +from rest_framework import exceptions, status, viewsets from rest_framework.decorators import action from rest_framework.filters import SearchFilter from rest_framework.permissions import IsAdminUser, IsAuthenticated @@ -26,7 +26,7 @@ class DistrictViewSet(viewsets.ReadOnlyModelViewSet): filterset_fields = ['county', ] -class SchoolViewSet(viewsets.ReadOnlyModelViewSet): +class SchoolViewSet(viewsets.ModelViewSet): """Školy""" queryset = School.objects.all() serializer_class = SchoolSerializer @@ -34,6 +34,15 @@ class SchoolViewSet(viewsets.ReadOnlyModelViewSet): filter_backends = [DjangoFilterBackend, SearchFilter] search_fields = ['name', 'street'] + def destroy(self, request, *args, **kwargs): + """Zmazanie školy""" + instance = self.get_object() + if Profile.objects.filter(school=instance).exists(): + raise exceptions.ValidationError( + detail='Nie je možné zmazať školu, ktorá má priradených užívateľov.') + self.perform_destroy(instance) + return Response(status=status.HTTP_204_NO_CONTENT) + class ProfileViewSet(viewsets.ModelViewSet): """Užívateľské profily"""