from documents.file_handling import create_source_path_directory
from documents.file_handling import delete_empty_directories
from documents.file_handling import generate_unique_filename
+from documents.models import CustomField
from documents.models import CustomFieldInstance
from documents.models import Document
from documents.models import MatchingModel
pass
+@receiver(models.signals.post_save, sender=CustomField)
+def update_cf_instance_documents(sender, instance: CustomField, **kwargs):
+ """
+ 'Select' custom field instances get their end-user value (e.g. in file names) from the select_options in extra_data,
+ which is contained in the custom field itself. So when the field is changed, we (may) need to update the file names
+ of all documents that have this custom field.
+ """
+ if (
+ instance.data_type == CustomField.FieldDataType.SELECT
+ ): # Only select fields, for now
+ for cf_instance in instance.fields.all():
+ update_filename_and_move_files(sender, cf_instance)
+
+
@receiver(models.signals.post_save, sender=CustomFieldInstance)
@receiver(models.signals.m2m_changed, sender=Document.tags.through)
@receiver(models.signals.post_save, sender=Document)
self.assertNotEqual(original_modified, doc.modified)
mock_move.assert_not_called()
+ @override_settings(
+ FILENAME_FORMAT="{{title}}_{{custom_fields|get_cf_value('test')}}",
+ )
+ @mock.patch("documents.signals.handlers.update_filename_and_move_files")
+ def test_select_cf_updated(self, m):
+ """
+ GIVEN:
+ - A document with a select type custom field
+ WHEN:
+ - The custom field select options are updated
+ THEN:
+ - The update_filename_and_move_files handler is called and the document filename is updated
+ """
+ cf = CustomField.objects.create(
+ name="test",
+ data_type=CustomField.FieldDataType.SELECT,
+ extra_data={
+ "select_options": ["apple", "banana", "cherry"],
+ },
+ )
+ doc = Document.objects.create(
+ title="document",
+ filename="document.pdf",
+ archive_filename="document.pdf",
+ checksum="A",
+ archive_checksum="B",
+ mime_type="application/pdf",
+ )
+ CustomFieldInstance.objects.create(field=cf, document=doc, value_select=0)
+
+ self.assertEqual(generate_filename(doc), "document_apple.pdf")
+
+ # handler should not have been called
+ self.assertEqual(m.call_count, 0)
+ cf.extra_data = {
+ "select_options": ["aubergine", "banana", "cherry"],
+ }
+ cf.save()
+ self.assertEqual(generate_filename(doc), "document_aubergine.pdf")
+ # handler should have been called
+ self.assertEqual(m.call_count, 1)
+
class TestFileHandlingWithArchive(DirectoriesMixin, FileSystemAssertsMixin, TestCase):
@override_settings(FILENAME_FORMAT=None)