samedi 11 août 2018

Django ImageField with tempfile

Folks, I need help understanding some details about how Django saves model files. I've written a test that involves creation of files (in a temporary directory via tempfile) and has the following lines:

TEMP_DIR = tempfile.TemporaryDirectory()
TEMP_DIR_PATH = TEMP_DIR.name
...

@override_settings(MEDIA_ROOT=TEMP_DIR_PATH)
def create_photo(self, album_number, photo_number):
    ...
    p = Photo.objects.create(
        number=photo_number,
        album=album,
        added_by=self.user,
        image=SimpleUploadedFile(
            name=...,
            content=open(..., 'rb').read(),
            content_type='image/jpeg'
        ),
        remarks='-'
    )
    p.full_clean()
    p.save()
    return p

This code works, except for one thing that confuses me. The line p = Photo.objects.create causes a file to appear in the temporary directory. Then p.full_clean() does nothing to the file. However when I execute p.save(), the file disappears from the temporary directory. If I remove p.save(), the file stays there when the function returns.

So my test function

def test_image_file_present(self):
    """When a photo is added to DB, the file actually appears in MEDIA."""
    p = self.create_photo(3, 2)
    image_filename = p.image.file.name
    if not os.path.exists(image_filename):
        self.fail('Image file not found')

fails if p.save() is there but passes if I remove p.save().

Why would object.save() cause the file to disappear?

As a bonus question, what's the purpose of .save() if the file and the Django model object appear already during Photo.objects.create? I've checked that the pre-save signal is sent by Photo.object.create() as well as by p.save().

Aucun commentaire:

Enregistrer un commentaire