Django:有什么方法可以改变FileField的"upload_to"属性而不诉诸魔术?

Jam*_*mes 2 python django

看到这篇博客文章 ...它已经很老了,所以也许情况发生了变化.但在我的实验中他们没有.为了upload_to动态更改模型字段FileField 路径,您必须求助于使用signals和创建自定义model fields.讨厌.我无法想象拥有动态上传路径是一个特殊的用例,标准的Django框架无法解决这个问题.我错过了什么吗?有没有其他方法可以实现这一目标?

本质上我想这样做:

def MyModel(models.Model):
    fileUpload = models.FileField(upload_to='media/', null=True, blank=True)

def save(self, **kwargs):
    # Retrieve the user's id/pk from their profile
    up = UserProfile.objects.get(email=self.email)

    # All their uploads go into their own directory
    self.file_image.upload_to = up.id

    super(MyModel, self).save()
Run Code Online (Sandbox Code Playgroud)

然而,在我尝试的10种不同的实现中,Django讨厌所有这些.特别是对于这个,文件被上传到默认路径'media/'.

我已经尝试抓取参数的模型表并将这些参数传递到dict对象,创建MyModel对象,设置MyModel.fileUpload.upload_to参数,然后将dict复制到模型中并保存.不行.

我也试图覆盖这个__init__方法,但猜猜是什么?那是在对象创建的早期,它实际上还没有self.email定义!所以这不起作用.

任何想法或我必须遵循原始链接中概述的神秘解决方案?

mgr*_*chy 6

所以实际上有一个相当简单的解决方案,在FileField' field, theupload_to keyword argument can actually take a function as a parameter. The function that you specify in yourupload_to`kwarg中应该有这个签名.

def my_awesome_upload_function(instance, filename):
    """ this function has to return the location to upload the file """

     return os.path.join('/media/%s/' % instance.id, filename)
Run Code Online (Sandbox Code Playgroud)

在这种情况下,instance是具有FileField的模型实例,filename是上载文件的文件名.所以你上面的例子中的模型看起来像这样:

def MyModel(models.Model):
    fileUpload = models.FileField(upload_to=my_awesome_upload_function, null=True, blank=True)
Run Code Online (Sandbox Code Playgroud)

如果这有意义,您现在my_awesome_upload_function可以根据您的偏好更改为生成上传文件的路径,给定已上载文件的模型实例和文件名.

  • 你不应该包含`/ media /'部分.返回的路径与`MEDIA_ROOT`设置中定义的路径相关. (2认同)