mar*_*oxe 4 directory django filefield
我有一个抽象的模型类UploadItem来处理上传的文件.我希望每个子类能够定义upload_to路径.为此,我将回调传递给FileField的构造函数.
这是一个例子:
class UploadItem(models.Model):
file = models.FileField(upload_to=UploadItem.get_directory)
class Meta:
abstract = True
# I want videos to be storred in 'videos/' directory
class Video(UploadItem):
def get_directory(self, instance, filename):
return 'videos/'
Run Code Online (Sandbox Code Playgroud)
但这不起作用,我收到此错误:
file = models.FileField(upload_to=UploadItem.get_directory)
NameError: name 'UploadItem' is not defined
Run Code Online (Sandbox Code Playgroud)
如果您需要使用基类属性作为子类的一部分,可以通过类似的方式进行一些调整来完成:
import os
# ...
def get_directory(instance, filename):
return instance.get_file_directory(filename)
class UploadItem(models.Model):
FILE_DIRECTORY = 'files/'
file = models.FileField(upload_to=get_directory)
class Meta:
abstract = True
@staticmethod
def get_file_directory(filename):
return os.path.join(UploadItem.FILE_DIRECTORY, filename)
Run Code Online (Sandbox Code Playgroud)
然后在子类中:
class Video(UploadItem):
FILE_DIRECTORY = 'videos/'
def get_file_directory(self, filename):
filename = os.path.join(self.FILE_DIRECTORY, filename)
return super().get_document_path(filename)
Run Code Online (Sandbox Code Playgroud)
这样你就会得到upload_to等于:
files为了UploadItemfiles/videos为了Video对于需要共享一些公共基本属性的更复杂的对象可能有用。
鉴于评估时错误是自然的
file = models.FileField(upload_to=UploadItem.get_directory)
Run Code Online (Sandbox Code Playgroud)
在UploadItem类尚未确定.您可以执行以下操作以使其工作:
def get_directory():
pass
class UploadItem(models.Model):
file = models.FileField(upload_to=get_directory)
class Meta:
abstract = True
Run Code Online (Sandbox Code Playgroud)
但这并不能解决你所有的问题.get_directory在Video类中添加(或覆盖)方法不会更改模型upload_to属性的file属性.
更新
该文件说,upload_to可能是一个可调用.
这也可以是可调用的,例如函数,它将被调用以获得上载路径,包括文件名.这个callable必须能够接受两个参数,并返回一个Unix风格的路径(带有正斜杠)以传递给存储系统.
鉴于此,我们可以编写一个自定义回调函数,如下所示:
categories_and_paths = { 'video': 'videos/', 'photo': 'photos/' } # etc.
def get_directory(instance, filename):
category = instance.category
return categories_and_paths.get(category, '')
Run Code Online (Sandbox Code Playgroud)
Instance这里将是相应模型的实例.为此,每个模型实例都应该有一个类别字段.我们可以在模型的主体中添加一个.
class Video(UploadItem):
category = 'video'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1548 次 |
| 最近记录: |