From bb83c1eb0ae32b17115d6f31bb2ca2cd5bbe9190 Mon Sep 17 00:00:00 2001 From: shamoon <4887959+shamoon@users.noreply.github.com> Date: Tue, 9 Jul 2024 09:57:53 -0700 Subject: [PATCH] Chore: upgrade to DRF 3.15 (#7134) --- .github/dependabot.yml | 5 -- Pipfile | 2 +- Pipfile.lock | 10 +-- ...ent_owner_alter_document_owner_and_more.py | 88 +++++++++++++++++++ src/documents/models.py | 1 + src/documents/serialisers.py | 37 +++++--- .../tests/test_migration_workflows.py | 7 +- ...unt_owner_alter_mailrule_owner_and_more.py | 52 +++++++++++ 8 files changed, 178 insertions(+), 24 deletions(-) create mode 100644 src/documents/migrations/1051_alter_correspondent_owner_alter_document_owner_and_more.py create mode 100644 src/paperless_mail/migrations/0025_alter_mailaccount_owner_alter_mailrule_owner_and_more.py diff --git a/.github/dependabot.yml b/.github/dependabot.yml index d6f6b4efd..1ed22b439 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -49,11 +49,6 @@ updates: - "paperless-ngx/backend" ignore: - dependency-name: "uvicorn" - - dependency-name: "djangorestframework" - versions: - - "3.15.0" - - "3.15.1" - - "3.15.2" groups: development: patterns: diff --git a/Pipfile b/Pipfile index 77bb99bcf..43f6bb600 100644 --- a/Pipfile +++ b/Pipfile @@ -18,7 +18,7 @@ django-filter = "~=24.2" django-guardian = "*" django-multiselectfield = "*" django-soft-delete = "*" -djangorestframework = "==3.14.0" +djangorestframework = "==3.15.2" djangorestframework-guardian = "*" drf-writable-nested = "*" bleach = "*" diff --git a/Pipfile.lock b/Pipfile.lock index cda0f7681..41b105e3c 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "272a69e9011a60f2d326b77d99d261425b66ebcc8ae929372213700ae47de0f5" + "sha256": "dfe78ffea6031e95e8e1ba35b668dacb08a4383b80d3d51d9fca239c4317d194" }, "pipfile-spec": 6, "requires": {}, @@ -552,12 +552,12 @@ }, "djangorestframework": { "hashes": [ - "sha256:579a333e6256b09489cbe0a067e66abe55c6595d8926be6b99423786334350c8", - "sha256:eb63f58c9f218e1a7d064d17a70751f528ed4e1d35547fdade9aaf4cd103fd08" + "sha256:2b8871b062ba1aefc2de01f773875441a961fefbf79f5eed1e32b2f096944b20", + "sha256:36fe88cd2d6c6bec23dca9804bab2ba5517a8bb9d8f47ebc68981b56840107ad" ], "index": "pypi", - "markers": "python_version >= '3.6'", - "version": "==3.14.0" + "markers": "python_version >= '3.8'", + "version": "==3.15.2" }, "djangorestframework-guardian": { "hashes": [ diff --git a/src/documents/migrations/1051_alter_correspondent_owner_alter_document_owner_and_more.py b/src/documents/migrations/1051_alter_correspondent_owner_alter_document_owner_and_more.py new file mode 100644 index 000000000..e8f0bb97c --- /dev/null +++ b/src/documents/migrations/1051_alter_correspondent_owner_alter_document_owner_and_more.py @@ -0,0 +1,88 @@ +# Generated by Django 4.2.13 on 2024-07-09 16:39 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations +from django.db import models + + +class Migration(migrations.Migration): + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("documents", "1050_customfield_extra_data_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="correspondent", + name="owner", + field=models.ForeignKey( + blank=True, + default=None, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + verbose_name="owner", + ), + ), + migrations.AlterField( + model_name="document", + name="owner", + field=models.ForeignKey( + blank=True, + default=None, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + verbose_name="owner", + ), + ), + migrations.AlterField( + model_name="documenttype", + name="owner", + field=models.ForeignKey( + blank=True, + default=None, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + verbose_name="owner", + ), + ), + migrations.AlterField( + model_name="savedview", + name="owner", + field=models.ForeignKey( + blank=True, + default=None, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + verbose_name="owner", + ), + ), + migrations.AlterField( + model_name="storagepath", + name="owner", + field=models.ForeignKey( + blank=True, + default=None, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + verbose_name="owner", + ), + ), + migrations.AlterField( + model_name="tag", + name="owner", + field=models.ForeignKey( + blank=True, + default=None, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + verbose_name="owner", + ), + ), + ] diff --git a/src/documents/models.py b/src/documents/models.py index 0e6de5360..2fc9a5774 100644 --- a/src/documents/models.py +++ b/src/documents/models.py @@ -34,6 +34,7 @@ class ModelWithOwner(models.Model): User, blank=True, null=True, + default=None, on_delete=models.SET_NULL, verbose_name=_("owner"), ) diff --git a/src/documents/serialisers.py b/src/documents/serialisers.py index 2f6a19f49..38f6cc4f9 100644 --- a/src/documents/serialisers.py +++ b/src/documents/serialisers.py @@ -261,13 +261,36 @@ class OwnedObjectSerializer( ) # other methods in mixin + def validate_unique_together(self, validated_data, instance=None): + # workaround for https://github.com/encode/django-rest-framework/issues/9358 + if "owner" in validated_data and "name" in self.Meta.fields: + name = validated_data.get("name", instance.name if instance else None) + objects = ( + self.Meta.model.objects.exclude(pk=instance.pk) + if instance + else self.Meta.model.objects.all() + ) + not_unique = objects.filter( + owner=validated_data["owner"], + name=name, + ).exists() + if not_unique: + raise serializers.ValidationError( + {"error": "Object violates owner / name unique constraint"}, + ) + def create(self, validated_data): # default to current user if not set - if "owner" not in validated_data and self.user: + request = self.context.get("request") + if ( + "owner" not in validated_data + or (request is not None and "owner" not in request.data) + ) and self.user: validated_data["owner"] = self.user permissions = None if "set_permissions" in validated_data: permissions = validated_data.pop("set_permissions") + self.validate_unique_together(validated_data) instance = super().create(validated_data) if permissions is not None: self._set_permissions(permissions, instance) @@ -276,17 +299,7 @@ class OwnedObjectSerializer( def update(self, instance, validated_data): if "set_permissions" in validated_data: self._set_permissions(validated_data["set_permissions"], instance) - if "owner" in validated_data and "name" in self.Meta.fields: - name = validated_data.get("name", instance.name) - not_unique = ( - self.Meta.model.objects.exclude(pk=instance.pk) - .filter(owner=validated_data["owner"], name=name) - .exists() - ) - if not_unique: - raise serializers.ValidationError( - {"error": "Object violates owner / name unique constraint"}, - ) + self.validate_unique_together(validated_data, instance) return super().update(instance, validated_data) diff --git a/src/documents/tests/test_migration_workflows.py b/src/documents/tests/test_migration_workflows.py index 507cb0c18..403067ca6 100644 --- a/src/documents/tests/test_migration_workflows.py +++ b/src/documents/tests/test_migration_workflows.py @@ -5,7 +5,12 @@ from documents.tests.utils import TestMigrations class TestMigrateWorkflow(TestMigrations): migrate_from = "1043_alter_savedviewfilterrule_rule_type" migrate_to = "1044_workflow_workflowaction_workflowtrigger_and_more" - dependencies = (("paperless_mail", "0024_alter_mailrule_name_and_more"),) + dependencies = ( + ( + "paperless_mail", + "0025_alter_mailaccount_owner_alter_mailrule_owner_and_more", + ), + ) def setUpBeforeMigration(self, apps): User = apps.get_model("auth", "User") diff --git a/src/paperless_mail/migrations/0025_alter_mailaccount_owner_alter_mailrule_owner_and_more.py b/src/paperless_mail/migrations/0025_alter_mailaccount_owner_alter_mailrule_owner_and_more.py new file mode 100644 index 000000000..308ebdf15 --- /dev/null +++ b/src/paperless_mail/migrations/0025_alter_mailaccount_owner_alter_mailrule_owner_and_more.py @@ -0,0 +1,52 @@ +# Generated by Django 4.2.13 on 2024-07-09 16:39 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations +from django.db import models + + +class Migration(migrations.Migration): + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("paperless_mail", "0024_alter_mailrule_name_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="mailaccount", + name="owner", + field=models.ForeignKey( + blank=True, + default=None, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + verbose_name="owner", + ), + ), + migrations.AlterField( + model_name="mailrule", + name="owner", + field=models.ForeignKey( + blank=True, + default=None, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + verbose_name="owner", + ), + ), + migrations.AlterField( + model_name="processedmail", + name="owner", + field=models.ForeignKey( + blank=True, + default=None, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + verbose_name="owner", + ), + ), + ]