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?
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()