diff --git a/formbuilder/models.py b/formbuilder/models.py index 9f8237e..37601bc 100644 --- a/formbuilder/models.py +++ b/formbuilder/models.py @@ -1,3 +1,4 @@ +from django.core.exceptions import ValidationError from django.db import models from django.db.models import UniqueConstraint from django.utils.translation import gettext_lazy as _ @@ -100,3 +101,7 @@ class Answer(UUIDModel): def __str__(self): return f"{self.submission} - {self.field}" + + def clean(self): + if self.field_id and self.submission_id and self.field.form_id != self.submission.form_id: + raise ValidationError({"field": _("Must belong to the same form as the submission.")}) diff --git a/formbuilder/tests.py b/formbuilder/tests.py index d0610ca..cfa884a 100644 --- a/formbuilder/tests.py +++ b/formbuilder/tests.py @@ -1,6 +1,7 @@ from datetime import timedelta from django import forms +from django.core.exceptions import ValidationError from django.db import IntegrityError from django.db.models import ProtectedError from django.test import TestCase @@ -329,3 +330,20 @@ class FormReportTests(FormbuilderTestBase): self.assertEqual(report.count, 0) self.assertEqual(report.rows, []) + + +class AnswerCleanTests(FormbuilderTestBase): + def test_rejects_field_from_another_form(self): + other_form = Form.objects.create(club=self.club, title="Other", slug="other") + other_field = Field.objects.create(form=other_form, key="x", label="X", order=1) + submission = Submission.objects.create(form=self.form, member=self.member) + answer = Answer(submission=submission, field=other_field, value="v") + + with self.assertRaises(ValidationError) as ctx: + answer.full_clean() + self.assertIn("field", ctx.exception.error_dict) + + def test_accepts_field_from_the_submissions_form(self): + submission = Submission.objects.create(form=self.form, member=self.member) + + Answer(submission=submission, field=self.name, value="v").full_clean()