django-在视图中将upload_设置为

django-在视图中将upload_设置为,django,file-upload,filefield,Django,File Upload,Filefield,我有一个存储文件的模型: class AFile(models.Model): path = models.CharField(max_length=256) name = models.CharField(max_length=256) file = models.FileField(upload_to=get_path) 有许多保存文件的视图。我想要一个单独的路径为每个。所以我把path放在模型中,并在get path函数中使用它。像这样: afile = AFil

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

class AFile(models.Model):
    path = models.CharField(max_length=256)
    name = models.CharField(max_length=256)
    file = models.FileField(upload_to=get_path)
有许多保存文件的视图。我想要一个单独的路径为每个。所以我把path放在模型中,并在get path函数中使用它。像这样:

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

所以文件在正确的位置。但我并不想在数据库中存储path和name字段,它只是用来生成路径。如果没有额外的模型字段,有什么方法可以实现同样的效果?

为什么不从实例生成路径

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)

为什么不从实例生成路径

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)

这里的问题是,
upload\u to
仅在模型上定义
FileField
ImageField
时可用。对该字段的任何后续访问都会返回一个
FieldFile
实例,该实例无权访问定义的
upload\u to
。长话短说,在最初定义方法之后,无法对其进行更改

但是,您可能可以围绕它进行一种结束运行。请注意,我实际上还没有尝试过这个方法,但它应该可以工作:

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

def set_upload_to_info(self, path, name):
    self.upload_to_info = (path, name)
afile.set_upload_to_info(path, name)
afile.save()
然后,在
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
然后在视图中,只需在保存模型之前调用创建的方法:

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

这里的问题是,
upload\u to
仅在模型上定义
FileField
ImageField
时可用。对该字段的任何后续访问都会返回一个
FieldFile
实例,该实例无权访问定义的
upload\u to
。长话短说,在最初定义方法之后,无法对其进行更改

但是,您可能可以围绕它进行一种结束运行。请注意,我实际上还没有尝试过这个方法,但它应该可以工作:

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

def set_upload_to_info(self, path, name):
    self.upload_to_info = (path, name)
afile.set_upload_to_info(path, name)
afile.save()
然后,在
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
然后在视图中,只需在保存模型之前调用创建的方法:

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

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

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

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

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

上传到参数可以通过更改
字段在视图中进行更改。保存模型前,上传到
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\u更改为
,以指向所需的路径。请告知此方法是否解决了您的问题。

上传到参数可以通过更改
字段在视图中进行更改。保存模型之前,请将上传到
文件字段的
属性。在我的例子中,我将基于类的视图与表单一起使用。所以在模型实例之前。我使用下面的代码更改上传路径

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\u更改为
,以指向所需的路径。请告知此方法是否解决了您的问题。

类似方法的可能重复是,但这种情况下的解决方案是使用模型中的信息。我的问题是,在模型中不包含信息的情况下,如何做到这一点。类似信息的可能重复是的,但这种情况下的解决方案是使用模型中的信息。我的问题是如何在模型中没有包含信息的情况下做到这一点。我已经做到了这一点。关键是我不想要硬编码的前缀。我想在视图中选择一个前缀。如果可能的话,我想避免在模型中保存前缀。只需在表单或表单集中添加表单字段?我已经做到了这一点。关键是我不想要硬编码的前缀。我想在视图中选择一个前缀。如果可能的话,我想避免在模型中保存前缀,除非我也保存前缀,否则我不能。只需在表单或表单集中添加表单字段?