Django:如何在FileField保存原始文件名?

时间:2022-01-02 20:16:31

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

我希望文件名是随机的,因此我使用upload_to函数返回一个随机文件名:

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.

谢谢你!

3 个解决方案

#1


8  

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.

这行不通,因为当需要FileField的实际值时,pre_save()调用upload_to()。您可以发现,上载()中的属性文件名的分配是在生成插入sql中的第一个param文件名之后进行的。因此,赋值不会在生成的SQL中生效,只会影响实例本身。

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

如果不是这个问题,请将您在shell中键入的代码发布。

#2


1  

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.

您可以在保存过程中执行填充文件名的路径。显然,在运行get_random_filename时,必须将原始文件名存储在内存中。

# 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...

#3


-1  

Just re-order your commands. https://docs.djangoproject.com/en/dev/topics/db/models/

只是再订购你的命令。https://docs.djangoproject.com/en/dev/topics/db/models/

def save(self, *args, **kwargs):
        do_something()
        super(Blog, self).save(*args, **kwargs) # Call the "real" save() method.
        do_something_else()

#1


8  

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.

这行不通,因为当需要FileField的实际值时,pre_save()调用upload_to()。您可以发现,上载()中的属性文件名的分配是在生成插入sql中的第一个param文件名之后进行的。因此,赋值不会在生成的SQL中生效,只会影响实例本身。

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

如果不是这个问题,请将您在shell中键入的代码发布。

#2


1  

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.

您可以在保存过程中执行填充文件名的路径。显然,在运行get_random_filename时,必须将原始文件名存储在内存中。

# 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...

#3


-1  

Just re-order your commands. https://docs.djangoproject.com/en/dev/topics/db/models/

只是再订购你的命令。https://docs.djangoproject.com/en/dev/topics/db/models/

def save(self, *args, **kwargs):
        do_something()
        super(Blog, self).save(*args, **kwargs) # Call the "real" save() method.
        do_something_else()