Skip to content

Custom saving path for FileField

August 30th, 2010 - (1 min)

Saving FileFields is pretty annoying anyway (all the manual stuff, saving chunks by hand…). The top bother is actually the limited way of creating paths: In MEDIA_ROOT, only with strftime arguments. While this does limit the number of files in a directory, it’s not as customisable as it should… So, here’s the alternative:

def get_path(instance, filename):
    ctype = ContentType.objects.get_for_model(instance)
    model = ctype.model.lower()
    app = ctype.app_label
    extension = filename.split('.')[-1]

    dir = model
    try:
        user = instance.user.username
    except:
        user = 'anon'

    chars = string.letters + string.digits
    name = string.join(random.sample(chars, 8), '')

    # debug
    #
    print (app, dir, user, name, extension)

    return "%s/%s/%s/%s.%s" % (settings.DOWNLOAD_PATH, dir, user, name, extension)

…and

# Excel file
class ExcelFileModel(models.Model):
    '''
    This class defines the parameters for an uploaded file

    @param file: The excel file
    @param user: The user who uploaded the file
    @param archive: A flag to identify if there is an archive we deal with (zip)
    @param type: File type (archive/format/program...)
    @param parent: The parent file (Parent file is an archive. Empty otherwise)
    '''

    FILE_CHOICES = (
        (u'F', u'Format'),
        (u'P', u'Program'),
    )
    user = models.ForeignKey(User)
    file = models.FileField(upload_to=get_path)

Now, your files are going to be saved in a path containing the username, with a mangled local name (so the only way to see which file it is and what’s supposed to do is to look in the database). Cute.

Share on

A little experiment: