mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-06-10 15:49:45 +00:00
Fixhancement: include trashed documents in document exporter/importer
This commit is contained in:
@@ -388,7 +388,7 @@ class Command(CryptMixin, PaperlessCommand):
|
||||
"custom_field_instances": CustomFieldInstance.objects.all(),
|
||||
"app_configs": ApplicationConfiguration.objects.all(),
|
||||
"notes": Note.objects.all(),
|
||||
"documents": Document.objects.order_by("id").all(),
|
||||
"documents": Document.global_objects.order_by("id").all(),
|
||||
"social_accounts": SocialAccount.objects.all(),
|
||||
"social_apps": SocialApp.objects.all(),
|
||||
"social_tokens": SocialToken.objects.all(),
|
||||
@@ -443,7 +443,7 @@ class Command(CryptMixin, PaperlessCommand):
|
||||
writer.write_batch(batch)
|
||||
|
||||
document_map: dict[int, Document] = {
|
||||
d.pk: d for d in Document.objects.order_by("id")
|
||||
d.pk: d for d in Document.global_objects.order_by("id")
|
||||
}
|
||||
|
||||
# 3. Export files from each document
|
||||
|
||||
@@ -125,7 +125,7 @@ class Command(CryptMixin, PaperlessCommand):
|
||||
"Found existing user(s), this might indicate a non-empty installation",
|
||||
),
|
||||
)
|
||||
if Document.objects.count() != 0:
|
||||
if Document.global_objects.count() != 0:
|
||||
self.stdout.write(
|
||||
self.style.WARNING(
|
||||
"Found existing documents(s), this might indicate a non-empty installation",
|
||||
@@ -376,7 +376,7 @@ class Command(CryptMixin, PaperlessCommand):
|
||||
]
|
||||
|
||||
for record in self.track(document_records, description="Copying files..."):
|
||||
document = Document.objects.get(pk=record["pk"])
|
||||
document = Document.global_objects.get(pk=record["pk"])
|
||||
|
||||
doc_file = record[EXPORTER_FILE_NAME]
|
||||
document_path = self.source / doc_file
|
||||
|
||||
@@ -389,7 +389,7 @@ class TestExportImport(
|
||||
self.assertIsFile(
|
||||
str(self.target / doc_from_manifest[EXPORTER_FILE_NAME]),
|
||||
)
|
||||
self.d3.delete()
|
||||
self.d3.hard_delete()
|
||||
|
||||
manifest = self._do_export()
|
||||
self.assertRaises(
|
||||
@@ -868,6 +868,62 @@ class TestExportImport(
|
||||
for obj in manifest:
|
||||
self.assertNotEqual(obj["model"], "auditlog.logentry")
|
||||
|
||||
def test_export_import_soft_deleted_document(self) -> None:
|
||||
"""
|
||||
GIVEN:
|
||||
- A document has been soft-deleted
|
||||
WHEN:
|
||||
- Export and re-import are performed
|
||||
THEN:
|
||||
- The soft-deleted document is included in the manifest
|
||||
- The soft-deleted document is re-imported successfully
|
||||
- The deleted_at timestamp is preserved after import
|
||||
"""
|
||||
shutil.rmtree(Path(self.dirs.media_dir) / "documents")
|
||||
shutil.copytree(
|
||||
Path(__file__).parent / "samples" / "documents",
|
||||
Path(self.dirs.media_dir) / "documents",
|
||||
)
|
||||
|
||||
# Soft-delete one document
|
||||
self.d2.delete()
|
||||
self.d2.refresh_from_db()
|
||||
self.assertIsNotNone(self.d2.deleted_at)
|
||||
|
||||
# Non-deleted documents visible via .objects should be 3
|
||||
self.assertEqual(Document.objects.count(), 3)
|
||||
# All documents including soft-deleted should be 4
|
||||
self.assertEqual(Document.global_objects.count(), 4)
|
||||
|
||||
manifest = self._do_export()
|
||||
|
||||
# Manifest must contain all 4 documents, including the soft-deleted one
|
||||
doc_records = [e for e in manifest if e["model"] == "documents.document"]
|
||||
self.assertEqual(len(doc_records), 4)
|
||||
|
||||
exported_pks = {r["pk"] for r in doc_records}
|
||||
self.assertIn(self.d2.pk, exported_pks)
|
||||
|
||||
# Re-import
|
||||
with paperless_environment():
|
||||
Document.global_objects.all().hard_delete()
|
||||
Correspondent.objects.all().delete()
|
||||
DocumentType.objects.all().delete()
|
||||
Tag.objects.all().delete()
|
||||
self.assertEqual(Document.global_objects.count(), 0)
|
||||
|
||||
call_command(
|
||||
"document_importer",
|
||||
"--no-progress-bar",
|
||||
self.target,
|
||||
skip_checks=True,
|
||||
)
|
||||
|
||||
self.assertEqual(Document.global_objects.count(), 4)
|
||||
# The soft-deleted document should still have deleted_at set
|
||||
reimported = Document.global_objects.get(pk=self.d2.pk)
|
||||
self.assertIsNotNone(reimported.deleted_at)
|
||||
|
||||
def test_export_data_only(self) -> None:
|
||||
"""
|
||||
GIVEN:
|
||||
|
||||
Reference in New Issue
Block a user