Search code examples
pythondjangodjango-south

FileField not respecting upload_to in the context of a South Migration


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?


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