Question

I recently changed the upload_to argument of a FileField, and now I am trying to write a South datamigration to move the files stored under the old system to the new system. I wrote some code that the FileField documentation indicated ought to work:

def forwards(self, orm):
    for mf in orm.ManagedFile.objects.all():
        print mf.content.path
        oldpath = mf.content.path
        cf = ContentFile(mf.content.read())
        cf.name = oldpath
        mf.content = cf
        mf.save()

This saves all the files according to some default rule, and they all end up loose in MEDIA_ROOT, rather than where the upload_to function dictates.

After some thought I understand why this is the case, but what can I do about it?

Was it helpful?

Solution

It is possible to manually re-attach the upload_to function like this:

 mf._meta.get_field('content').generate_filename = path_maker

The resulting code looks like this:

def path_maker(m_file, filename):
    ext = str(os.path.splitext(filename)[1])
    return os.path.join('m_files', m_file.hash) + ext

...

def forwards(self, orm):
    for mf in orm.ManagedFile.objects.all():
        mf._meta.get_field('content').generate_filename = path_maker
        print mf.content.path
        oldpath = mf.content.path
        cf = ContentFile(mf.content.read())
        cf.name = oldpath
        mf.content = cf
        mf.save()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top