From e4365848511a0a80640fa4b543003f1e6d1ef7e4 Mon Sep 17 00:00:00 2001 From: Sergei Maertens Date: Mon, 9 Dec 2024 16:03:30 +0100 Subject: [PATCH] :boom: [#3283] Make TemporaryFileUpload.submission non-nullable We've provided a transition period from Open Forms 2.7, which ensures that a submission is stored. Support for legacy uploads is now removed. The celery background jobs should by now have deleted all the old unclaimed uploads, unless absurdly large retention values have been set. --- docs/installation/upgrade-300.rst | 12 +++++++ src/openforms/formio/components/vanilla.py | 5 +-- ...non_legacy_submission_not_null_and_more.py | 32 +++++++++++++++++++ .../submissions/models/submission_files.py | 16 ---------- .../submissions/tests/test_models.py | 16 ---------- 5 files changed, 45 insertions(+), 36 deletions(-) create mode 100644 src/openforms/submissions/migrations/0013_remove_temporaryfileupload_non_legacy_submission_not_null_and_more.py diff --git a/docs/installation/upgrade-300.rst b/docs/installation/upgrade-300.rst index 82c096d543..02f3b24ad7 100644 --- a/docs/installation/upgrade-300.rst +++ b/docs/installation/upgrade-300.rst @@ -103,3 +103,15 @@ Removal of /api/v2/location/get-street-name-and-city endpoint The /api/v2/location/get-street-name-and-city was deprecated for some time, and is now removed in favor of the /api/v2/geo/address-autocomplete endpoint. + +Legacy temporary file uploads no longer supported +================================================= + +Before Open Forms 2.7.0, temporary file uploads (as created by the file upload form +component) would not be related to the submission they were uploaded in. We call these +legacy temporary file uploads, and support for them has been removed in Open Forms 3.0. + +The setting ``TEMPORARY_UPLOADS_REMOVED_AFTER_DAYS`` controls how long file uploads are +kept. Ensure that this many days have passed since the last legacy upload before +upgrading to Open Forms 3.0, otherwise you will run into database errors during the +upgrade. diff --git a/src/openforms/formio/components/vanilla.py b/src/openforms/formio/components/vanilla.py index ff866894b8..109cb0560d 100644 --- a/src/openforms/formio/components/vanilla.py +++ b/src/openforms/formio/components/vanilla.py @@ -383,10 +383,7 @@ def validate(self, attrs: dict[str, Any]) -> dict[str, Any]: {"originalName": _("Name does not match the uploaded file.")} ) - if ( - not temporary_upload.legacy - and temporary_upload.submission != self.context["submission"] - ): + if temporary_upload.submission != self.context["submission"]: raise serializers.ValidationError({"url": _("Invalid URL.")}) with temporary_upload.content.open("rb") as infile: diff --git a/src/openforms/submissions/migrations/0013_remove_temporaryfileupload_non_legacy_submission_not_null_and_more.py b/src/openforms/submissions/migrations/0013_remove_temporaryfileupload_non_legacy_submission_not_null_and_more.py new file mode 100644 index 0000000000..8807109dee --- /dev/null +++ b/src/openforms/submissions/migrations/0013_remove_temporaryfileupload_non_legacy_submission_not_null_and_more.py @@ -0,0 +1,32 @@ +# Generated by Django 4.2.17 on 2024-12-09 15:04 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ("submissions", "0012_alter_submission_price"), + ] + + operations = [ + migrations.RemoveConstraint( + model_name="temporaryfileupload", + name="non_legacy_submission_not_null", + ), + migrations.RemoveField( + model_name="temporaryfileupload", + name="legacy", + ), + migrations.AlterField( + model_name="temporaryfileupload", + name="submission", + field=models.ForeignKey( + help_text="Submission the temporary file upload belongs to.", + on_delete=django.db.models.deletion.CASCADE, + to="submissions.submission", + verbose_name="submission", + ), + ), + ] diff --git a/src/openforms/submissions/models/submission_files.py b/src/openforms/submissions/models/submission_files.py index 0d6998160c..c0f039c7c3 100644 --- a/src/openforms/submissions/models/submission_files.py +++ b/src/openforms/submissions/models/submission_files.py @@ -8,7 +8,6 @@ from django.core.files.base import File from django.db import models -from django.db.models import Q from django.utils import timezone from django.utils.translation import gettext_lazy as _ @@ -49,17 +48,9 @@ def select_prune(self, age: timedelta): class TemporaryFileUpload(DeleteFileFieldFilesMixin, models.Model): uuid = models.UUIDField(_("UUID"), unique=True, default=uuid.uuid4) - legacy = models.BooleanField( - _("legacy"), - default=False, - help_text=_("Whether the instance is linked to a submission instance."), - ) - # TODO DeprecationWarning null=True is a transitional state, and should be removed - # at some point: submission = models.ForeignKey( "submissions.Submission", on_delete=models.CASCADE, - null=True, verbose_name=_("submission"), help_text=_("Submission the temporary file upload belongs to."), ) @@ -83,13 +74,6 @@ class TemporaryFileUpload(DeleteFileFieldFilesMixin, models.Model): class Meta: verbose_name = _("temporary file upload") verbose_name_plural = _("temporary file uploads") - constraints = [ - models.CheckConstraint( - check=(Q(legacy=False) & Q(submission__isnull=False)) - | (Q(legacy=True) & Q(submission__isnull=True)), - name="non_legacy_submission_not_null", - ), - ] class SubmissionFileAttachmentQuerySet( diff --git a/src/openforms/submissions/tests/test_models.py b/src/openforms/submissions/tests/test_models.py index 4f6b5ca2ce..5f82926c9f 100644 --- a/src/openforms/submissions/tests/test_models.py +++ b/src/openforms/submissions/tests/test_models.py @@ -589,19 +589,3 @@ def test_names_do_not_break_pdf_saving_to_disk(self): report.generate_submission_report_pdf() self.assertTrue(report.content.storage.exists(report.content.name)) - - -class TemporaryFileUploadTests(TestCase): - def test_legacy_check_constraint(self): - with self.assertRaises(IntegrityError): - TemporaryFileUploadFactory.create( - submission=None, - legacy=False, - ) - - def test_non_legacy_check_constraint(self): - with self.assertRaises(IntegrityError): - TemporaryFileUploadFactory.create( - submission=SubmissionFactory.create(), - legacy=True, - )