From 1b7cef055d32822d9f5423fcc911d73471e6497e Mon Sep 17 00:00:00 2001 From: Rohan Moniz <60864468+rm03@users.noreply.github.com> Date: Sat, 25 Nov 2023 20:37:34 -0500 Subject: [PATCH] update validation logic and address comments --- .../migrations/0091_applicationextension.py | 3 +- backend/clubs/models.py | 3 ++ backend/clubs/serializers.py | 47 +++++++++++++++---- backend/clubs/views.py | 8 +--- 4 files changed, 46 insertions(+), 15 deletions(-) diff --git a/backend/clubs/migrations/0091_applicationextension.py b/backend/clubs/migrations/0091_applicationextension.py index ce4c5547f..43cd96efd 100644 --- a/backend/clubs/migrations/0091_applicationextension.py +++ b/backend/clubs/migrations/0091_applicationextension.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.18 on 2023-11-23 00:07 +# Generated by Django 3.2.18 on 2023-11-25 03:58 import django.db.models.deletion from django.conf import settings @@ -42,5 +42,6 @@ class Migration(migrations.Migration): ), ), ], + options={"unique_together": {("user", "application")}}, ), ] diff --git a/backend/clubs/models.py b/backend/clubs/models.py index a452f6a93..162e471bf 100644 --- a/backend/clubs/models.py +++ b/backend/clubs/models.py @@ -1603,6 +1603,9 @@ class ApplicationExtension(models.Model): ) end_time = models.DateTimeField() + class Meta: + unique_together = (("user", "application"),) + class ApplicationCommittee(models.Model): """ diff --git a/backend/clubs/serializers.py b/backend/clubs/serializers.py index cc564e74d..db3c13471 100644 --- a/backend/clubs/serializers.py +++ b/backend/clubs/serializers.py @@ -2444,12 +2444,6 @@ class Meta: "end_time", ) - def validate_username(self, value): - user = get_user_model().objects.filter(username=value).first() - if not user: - raise serializers.ValidationError("Please provide a valid username!") - return value - def create(self, validated_data): username = validated_data.get("user").pop("username") validated_data["user"] = get_user_model().objects.get(username=username) @@ -2462,13 +2456,50 @@ def create(self, validated_data): return super().create(validated_data) def update(self, instance, validated_data): - user_field = validated_data.pop("user", None) - if user_field: + if user_field := validated_data.pop("user", None): username = user_field.pop("username") user = get_user_model().objects.get(username=username) instance.user = user return super().update(instance, validated_data) + def validate(self, data): + username = None + if user_field := data.get("user") or not self.instance: + username = user_field.get("username") + user = get_user_model().objects.filter(username=username).first() + if not user: + raise serializers.ValidationError("Please provide a valid username!") + + application_pk = self.context["view"].kwargs.get("application_pk") + application = ClubApplication.objects.filter(pk=application_pk).first() + + if not application: + raise serializers.ValidationError("Invalid application id!") + + if ( + ( + not self.instance + or (username and self.instance.user.username != username) + ) + and ApplicationExtension.objects.filter( + user=user, application=application + ).exists() + ): + raise serializers.ValidationError( + "An extension for this user and application already exists!" + ) + + extension_end_time = data.get("end_time") + if ( + extension_end_time + and extension_end_time <= application.application_end_time + ): + raise serializers.ValidationError( + "Extension end time must be greater than the application end time!" + ) + + return data + class ApplicationSubmissionSerializer(serializers.ModelSerializer): committee = ApplicationCommitteeSerializer(required=False, read_only=True) diff --git a/backend/clubs/views.py b/backend/clubs/views.py index 42848a1fc..9a2415fe6 100644 --- a/backend/clubs/views.py +++ b/backend/clubs/views.py @@ -4458,11 +4458,7 @@ def question_response(self, *args, **kwargs): # prevent submissions outside of the open duration now = timezone.now() - extension = ( - application.extensions.filter(user=self.request.user) - .order_by("-end_time") - .first() - ) + extension = application.extensions.filter(user=self.request.user).first() end_time = ( max(extension.end_time, application.application_end_time) if extension @@ -4814,7 +4810,7 @@ def current(self, *args, **kwargs): - $ref: "#/components/schemas/ClubApplication" --- """ - qs = self.get_queryset() + qs = self.get_queryset().prefetch_related("extensions") now = timezone.now() user = self.request.user q = Q(application_end_time__gte=now)