Skip to content

Commit

Permalink
Ensure virtual FileField instances mirror FileField
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobwegner committed Jul 1, 2024
1 parent 593009b commit 7cd0a2b
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 6 deletions.
5 changes: 3 additions & 2 deletions modeltrans/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,9 @@ def get_localized_value(self, instance, field_name):
value = instance.i18n.get(field_name)

if isinstance(self.original_field, fields.files.FileField):
# TODO: Review this versus `descriptor_class`; need to write some additional tests to verify
return self.attr_class(instance, self, value)
descriptor = self.descriptor_class(self)
descriptor.__set__(instance, value)
return descriptor.__get__(instance)

return value

Expand Down
51 changes: 47 additions & 4 deletions tests/test_models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.core.exceptions import ValidationError
from django.core.files.base import ContentFile
from django.core.files.storage.memory import InMemoryFileNode
from django.db import DataError, models, transaction
from django.test import TestCase, override_settings
from django.utils.translation import override
Expand Down Expand Up @@ -144,12 +145,10 @@ def test_fallback_getting_FileField(self):
post = Post.objects.create(title="Test Post", is_published=True)
sample_file = ContentFile("sample content", name="sample-en.txt")
attachment = Attachment.objects.create(post=post, file=sample_file)
default_file_name = attachment.file.name
assert default_file_name

with override("fr"):
self.assertIsInstance(attachment.file_i18n, models.fields.files.FieldFile)
self.assertEqual(attachment.file_i18n.name, default_file_name)
self.assertIsInstance(attachment.file_i18n.file, InMemoryFileNode)

def test_set_FileField(self):
post = Post.objects.create(title="Test Post", is_published=True)
Expand All @@ -162,14 +161,58 @@ def test_set_FileField(self):
attachment = Attachment.objects.create(
post=post, file=sample_file_en, file_fr=sample_file_fr
)
self.assertIsInstance(attachment.file_fr, models.fields.files.FieldFile)

self.assertIsInstance(attachment.file.file, InMemoryFileNode)
self.assertIsInstance(attachment.file_fr.file, InMemoryFileNode)

saved_fr_content = attachment.file_fr.read().decode("utf-8")
self.assertEqual(saved_fr_content, fr_content)
self.assertIsInstance(attachment.file_fr, models.fields.files.FieldFile)

with override("fr"):
self.assertEqual(attachment.file_i18n, attachment.file_fr)

def test_FileField_getter(self):
post = Post.objects.create(title="Test Post", is_published=True)

fr_content = "exemple de contenu 2"
sample_file_fr = ContentFile(fr_content, name="sample-fr-2.txt")

attachment = Attachment(post=post, file_fr=sample_file_fr)
# prior to invoking save, the file_fr should be an instance of FieldFile
self.assertIsInstance(attachment.file_fr, models.fields.files.FieldFile)
# but the file object should be an instance of ContentFile
self.assertIsInstance(attachment.file_fr.file, ContentFile)
attachment.save()

# After saving, the file object should be the default storage class
self.assertIsInstance(attachment.file_fr.file, InMemoryFileNode)

# Retreiving the instance from the database, file and file_fr
# should return the same kind of interface (a FieldFile instance)
attachment = Attachment.objects.get(pk=attachment.pk)
self.assertIsInstance(attachment.file, models.fields.files.FieldFile)
self.assertIsInstance(attachment.file_fr, models.fields.files.FieldFile)

# Test that we can overwrite those with new content
new_content = "new content"
new_fr_content = "new French content"
attachment.file = ContentFile(new_content, name="content-new.txt")
attachment.file_fr = ContentFile(new_fr_content, name="content-new-fr.txt")
self.assertIsInstance(attachment.file, models.fields.files.FieldFile)
self.assertIsInstance(attachment.file_fr, models.fields.files.FieldFile)

attachment.save()

self.assertIsInstance(attachment.file_fr, models.fields.files.FieldFile)
self.assertIsInstance(attachment.file, models.fields.files.FieldFile)

with attachment.file.open() as f:
self.assertEqual(f.read().decode("utf-8"), new_content)

with attachment.file_fr.open() as f:
self.assertEqual(f.read().decode("utf-8"), new_fr_content)

def test_creating_using_virtual_default_language_field(self):
m = Blog.objects.create(title_en="Falcon")

Expand Down

0 comments on commit 7cd0a2b

Please sign in to comment.