0

我有一个用于存储文件的模型:

class AFile(models.Model):
    path = models.CharField(max_length=256)
    name = models.CharField(max_length=256)
    file = models.FileField(upload_to=get_path)

有许多保存文件的视图。我想要一个单独的路径。所以我把路径放在模型中并在获取路径函数中使用它。像这样:

afile = AFile(path='blah/foo/', name='filex.jpg')
afile.save()

所以文件在正确的位置。但我真的不想将路径和名称字段存储在我的数据库中,它只是用来生成路径。有什么方法可以在没有额外模型字段的情况下实现同样的目标?

4

4 回答 4

3

这里的问题是只有在模型上定义orupload_to时才可用。对该字段的任何后续访问都会返回一个实例,该实例无权访问定义的. 总而言之,在最初定义方法后,无法更改方法。FileFieldImageFieldFieldFileupload_to

但是,您也许可以围绕它进行某种最终运行。请注意,我实际上并没有尝试过,但它应该可以工作:

首先在您的模型上定义一个方法,该方法将具有在模型上设置实例变量的简单任务:

def set_upload_to_info(self, path, name):
    self.upload_to_info = (path, name)

然后,在您的upload_to方法中,您可以测试这些属性是否存在,并在它们存在时使用它们:

def my_upload_to(instance, filename):
    if hasattr(instance, 'upload_to_info'):
        path, name = instance.upload_to_info
        # do something and return file path
    else:
        # standard upload_to bit here

那么在你看来,你只需要在保存模型之前调用你创建的方法:

afile.set_upload_to_info(path, name)
afile.save()
于 2012-08-03T15:11:15.273 回答
2

上传到参数可以通过在保存模型之前更改field.upload_to属性来更改。FileField就我而言,我将基于类的视图与表单一起使用。所以在模型实例之前。我使用下面的代码将上传更改为路径。

with transaction.atomic():
        model_instance = form.save(commit=False)
        model_instance.creator = self.request.user
        model_instance.img_field.field.upload_to = 'directory/'+model_instance.name+'/logo'
        self.object = form.save()

简而言之,如果您的图像字段被命名为 imageupload,imageupload.field.upload_to请相应地更改以指向您需要的路径。请告知此方法是否解决了您的问题。

于 2016-10-13T10:20:52.397 回答
1

为什么不从实例生成路径?

def generate_path(instance, filename):
    return os.path.join("hardcoded_prefix", instance.name, filename)

class AFile(models.Model):
    name = models.CharField(max_length=256)
    file = models.FileField(upload_to=generate_path)
于 2012-08-03T13:18:59.817 回答
0

解决办法是放入一些非持久化的字段,仍然在get_path方法中引用它们

class AFile(models.Model):
    name = models.CharField(max_length=256)
    file = models.FileField(upload_to=get_path)
    path = ''
于 2012-08-05T07:40:55.940 回答