From 464e57cb9eceeb5c1dbf85abdca0d95fa39b3535 Mon Sep 17 00:00:00 2001 From: Cody Maffucci <46459665+Maffooch@users.noreply.github.com> Date: Fri, 16 Feb 2024 20:11:22 -0600 Subject: [PATCH 1/2] Questionnaires: Correct nested object deletions --- dojo/models.py | 10 +++++++++- dojo/survey/views.py | 21 ++++++++++++--------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/dojo/models.py b/dojo/models.py index 45d522963ee..174e189a14c 100755 --- a/dojo/models.py +++ b/dojo/models.py @@ -27,6 +27,7 @@ from django.utils.html import escape from pytz import all_timezones from polymorphic.models import PolymorphicModel +from polymorphic.managers import PolymorphicManager from multiselectfield import MultiSelectField from django import forms from django.utils.translation import gettext as _ @@ -4355,6 +4356,8 @@ class Meta: help_text=_("If selected, user doesn't have to answer this question")) text = models.TextField(blank=False, help_text=_('The question text'), default='') + objects = models.Manager() + polymorphic = PolymorphicManager() def __str__(self): return self.text @@ -4364,6 +4367,7 @@ class TextQuestion(Question): ''' Question with a text answer ''' + objects = PolymorphicManager() def get_form(self): ''' @@ -4397,8 +4401,8 @@ class ChoiceQuestion(Question): multichoice = models.BooleanField(default=False, help_text=_("Select one or more")) - choices = models.ManyToManyField(Choice) + objects = PolymorphicManager() def get_form(self): ''' @@ -4476,6 +4480,8 @@ class Answer(PolymorphicModel, TimeStampedModel): null=False, blank=False, on_delete=models.CASCADE) + objects = models.Manager() + polymorphic = PolymorphicManager() class TextAnswer(Answer): @@ -4483,6 +4489,7 @@ class TextAnswer(Answer): blank=False, help_text=_('The answer text'), default='') + objects = PolymorphicManager() def __str__(self): return self.answer @@ -4492,6 +4499,7 @@ class ChoiceAnswer(Answer): answer = models.ManyToManyField( Choice, help_text=_('The selected choices as the answer')) + objects = PolymorphicManager() def __str__(self): if len(self.answer.all()): diff --git a/dojo/survey/views.py b/dojo/survey/views.py index f3043b1b757..0b5013aaa00 100644 --- a/dojo/survey/views.py +++ b/dojo/survey/views.py @@ -36,9 +36,9 @@ def delete_engagement_survey(request, eid, sid): if request.method == 'POST': form = Delete_Questionnaire_Form(request.POST, instance=survey) if form.is_valid(): - answers = Answer.objects.filter( + answers = Answer.polymorphic.filter( question__in=[ - question.id for question in survey.survey.questions.all()], + question.id for question in Question.polymorphic.filter(engagement_survey=survey.survey)], answered_survey=survey) for answer in answers: answer.delete() @@ -95,7 +95,7 @@ def answer_questionnaire(request, eid, sid): prefix=str(q.id), answered_survey=survey, question=q, form_tag=False) - for q in survey.survey.questions.all()] + for q in Question.polymorphic.filter(engagement_survey=survey.survey)] questions_are_valid = [] @@ -184,7 +184,7 @@ def get_answered_questions(survey=None, read_only=False): answered_survey=survey, question=q, form_tag=False) - for q in survey.survey.questions.all()] + for q in Question.polymorphic.filter(engagement_survey=survey.survey)] if read_only: for question in questions: @@ -416,7 +416,7 @@ def questionnaire(request): @user_is_configuration_authorized('dojo.view_question') def questions(request): - questions = Question.objects.all() + questions = Question.polymorphic.all() questions = QuestionFilter(request.GET, queryset=questions) paged_questions = get_page_items(request, questions.qs, 25) add_breadcrumb(title="Questions", top_level=False, request=request) @@ -500,7 +500,10 @@ def create_question(request): @user_is_configuration_authorized('dojo.change_question') def edit_question(request, qid): - question = get_object_or_404(Question, id=qid) + try: + question = Question.polymorphic.get(id=qid) + except Question.DoesNotExist: + return Http404() survey = Engagement_Survey.objects.filter(questions__in=[question]) reverted = False answered = [] @@ -652,7 +655,7 @@ def delete_empty_questionnaire(request, esid): form = Delete_Questionnaire_Form(request.POST, instance=survey) if form.is_valid(): answers = Answer.objects.filter( - question__in=[question.id for question in survey.survey.questions.all()], + question__in=[question.id for question in Question.polymorphic.filter(engagement_survey=survey.survey)], answered_survey=survey) for answer in answers: answer.delete() @@ -740,7 +743,7 @@ def answer_empty_survey(request, esid): engagement_survey=engagement_survey, question=q, form_tag=False) - for q in engagement_survey.questions.all() + for q in Question.polymorphic.filter(engagement_survey=engagement_survey) ] if request.method == 'POST': @@ -753,7 +756,7 @@ def answer_empty_survey(request, esid): answered_survey=survey, question=q, form_tag=False) - for q in survey.survey.questions.all() + for q in Question.polymorphic.filter(engagement_survey=survey.survey) ] questions_are_valid = [] From ee98c88524b1333af79d0601269e7247adb1709e Mon Sep 17 00:00:00 2001 From: Cody Maffucci <46459665+Maffooch@users.noreply.github.com> Date: Tue, 20 Feb 2024 07:33:56 -0600 Subject: [PATCH 2/2] Fix Flake8 --- dojo/survey/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dojo/survey/views.py b/dojo/survey/views.py index 0b5013aaa00..02fc9f74d59 100644 --- a/dojo/survey/views.py +++ b/dojo/survey/views.py @@ -500,7 +500,7 @@ def create_question(request): @user_is_configuration_authorized('dojo.change_question') def edit_question(request, qid): - try: + try: question = Question.polymorphic.get(id=qid) except Question.DoesNotExist: return Http404()