Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: How to save original filename in FileField?

Tags:

python

django

I want the filenames to be random and therefore I use upload_to function which returns a random filename like so:

from uuid import uuid4
import os
def get_random_filename(instance, filename):
    ext = filename.split('.')[-1]
    filename = "%s.%s" % (str(uuid4()), ext)
    return os.path.join('some/path/', filename)

# inside the model
class FooModel(models.Model):
    file = models.FileField(upload_to=get_random_filename)

However I would like to save the original filename to an attribute inside the model. Something like this does not work:

def get_random_filename(instance, filename):
    instance.filename = filename
    ext = filename.split('.')[-1]
    filename = "%s.%s" % (str(uuid4()), ext)
    return os.path.join('some/path/', filename)

# inside the model
class FooModel(models.Model):
    file = models.FileField(upload_to=get_random_filename)
    filename = models.CharField(max_length=128)

How can I do it?

Thank you.

like image 661
miki725 Avatar asked Jun 05 '12 22:06

miki725


2 Answers

The posted code normally works, perhaps the actual code is

class FooModel(models.Model):
    filename = models.CharField(max_length=128)
    file = models.FileField(upload_to=get_random_filename)

Note the switching of the ordering of the fields above.

This won't work because: the upload_to() is invoked by the pre_save(), here in the code, when the actual value of the FileField is required. You could find that the assignment to the attribute filename in the upload() is after the generating of the first param filename in the inserting sql. Thus, the assignment does not take effect in the generated SQL and only affects the instance itself.

If that's not the issue, please post the code you typed in shell.

like image 101
okm Avatar answered Oct 20 '22 19:10

okm


You could go the route of populating the filename during the save process. Obviously you'll have to store the original file name in memory when your get_random_filename runs.

# inside the model
class FooModel(models.Model):
    file = models.FileField(upload_to=get_random_filename)
    filename = models.CharField(max_length=128)

    def save(self, force_insert=False, force_update=False):
        super(FooModel, self).save(force_insert, force_update)
            #Do your code here...
like image 43
magicTuscan Avatar answered Oct 20 '22 21:10

magicTuscan