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
Reddit
Linked in
Whatsapp

A little experiment: