feat: prevent two decisions with the same college

This commit is contained in:
Ethan Nguyen 2021-04-20 14:28:05 -04:00
parent 32cdd065d3
commit 4ef2e6b3a8
No known key found for this signature in database
GPG Key ID: B4CA5339AF911920
2 changed files with 55 additions and 3 deletions

View File

@ -4,6 +4,7 @@ from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit from crispy_forms.layout import Submit
from django import forms from django import forms
from django.core.exceptions import ValidationError
from tjdests.apps.authentication.models import User from tjdests.apps.authentication.models import User
from tjdests.apps.destinations.models import Decision, TestScore from tjdests.apps.destinations.models import Decision, TestScore
@ -36,6 +37,44 @@ class DecisionForm(forms.ModelForm):
model = Decision model = Decision
fields = ["college", "decision_type", "admission_status"] fields = ["college", "decision_type", "admission_status"]
def __init__(self, *args, **kwargs):
self.request = kwargs.pop("request", None)
self.is_edit = kwargs.pop("edit", False)
super().__init__(*args, **kwargs)
def clean(self) -> Dict[str, Any]:
cleaned_data = super().clean()
# Ensure that the college is not a duplicate for this user
# Yes, this is weird. Basically: if we are not editing
# (i.e. creating a new one), we make sure that
# the user does not have a Decision object with that college already.
# If we are editing, then we ensure that the college
# has not changed. If it has changed, then we
# make sure that the user does not have a Decision object with that college already.
if (
not self.is_edit
and Decision.objects.filter(
user=self.request.user, college=cleaned_data.get("college")
).count()
> 0
) or (
self.is_edit
and Decision.objects.filter(
user=self.request.user,
id=self.instance.id,
college=cleaned_data.get("college"),
).count()
!= 1
and Decision.objects.filter(
user=self.request.user, college=cleaned_data.get("college")
).count()
> 0
):
raise ValidationError("You cannot add a second entry for this college")
return cleaned_data
class TestScoreForm(forms.ModelForm): class TestScoreForm(forms.ModelForm):
class Meta: class Meta:

View File

@ -1,3 +1,5 @@
from typing import Any, Dict
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
@ -10,7 +12,7 @@ from django.views.generic import CreateView, DeleteView, UpdateView
from tjdests.apps.authentication.decorators import require_accept_tos from tjdests.apps.authentication.decorators import require_accept_tos
from tjdests.apps.destinations.models import Decision, TestScore from tjdests.apps.destinations.models import Decision, TestScore
from .forms import ProfilePublishForm, TestScoreForm from .forms import DecisionForm, ProfilePublishForm, TestScoreForm
@login_required @login_required
@ -103,7 +105,7 @@ class DecisionCreateView(
LoginRequiredMixin, SuccessMessageMixin, UserPassesTestMixin, CreateView LoginRequiredMixin, SuccessMessageMixin, UserPassesTestMixin, CreateView
): ):
model = Decision model = Decision
fields = ["college", "decision_type", "admission_status"] form_class = DecisionForm
template_name = "profile/decision_form.html" template_name = "profile/decision_form.html"
success_message = "Decision created successfully." success_message = "Decision created successfully."
@ -111,6 +113,11 @@ class DecisionCreateView(
form.instance.user = self.request.user form.instance.user = self.request.user
return super().form_valid(form) return super().form_valid(form)
def get_form_kwargs(self) -> Dict[str, Any]:
form_kwargs = super().get_form_kwargs()
form_kwargs["request"] = self.request
return form_kwargs
def test_func(self): def test_func(self):
return self.request.user.is_senior and self.request.user.accepted_terms return self.request.user.is_senior and self.request.user.accepted_terms
@ -122,7 +129,7 @@ class DecisionUpdateView(
LoginRequiredMixin, SuccessMessageMixin, UserPassesTestMixin, UpdateView LoginRequiredMixin, SuccessMessageMixin, UserPassesTestMixin, UpdateView
): ):
model = Decision model = Decision
fields = ["college", "decision_type", "admission_status"] form_class = DecisionForm
template_name = "profile/decision_form.html" template_name = "profile/decision_form.html"
success_message = "Decision created successfully." success_message = "Decision created successfully."
@ -130,6 +137,12 @@ class DecisionUpdateView(
form.instance.user = self.request.user form.instance.user = self.request.user
return super().form_valid(form) return super().form_valid(form)
def get_form_kwargs(self) -> Dict[str, Any]:
form_kwargs = super().get_form_kwargs()
form_kwargs["request"] = self.request
form_kwargs["edit"] = True
return form_kwargs
def get_queryset(self): def get_queryset(self):
owner = self.request.user owner = self.request.user
return self.model.objects.filter(user=owner) return self.model.objects.filter(user=owner)