我正在尝试为FileField建立路径,获取并使用该实例来获取URL的其他数据以及字段名,以得到类似的内容:
/media/documents/<instance_data>/<field_name>.pdf
我最好的工作方法是:
class UserDocFileField(models.FileField):
def get_fixed_folder_path(self, instance, filename):
return 'documents/{}/{}.pdf'.format(instance.user.rfc, self.name)
def __init__(self, *args, **kwargs):
kwargs["upload_to"] = self.get_fixed_folder_path
super(UserDocFileField, self).__init__(*args, **kwargs)
在我的模型中:
class Documents(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
file_1 = UserDocFileField()
file_2 = UserDocFileField()
# ... other documents
给我我想要的东西,即:
/media/documents/ABCD840422ABC/file_1.pdf
但是,这使Django每次运行makemigrations时都会生成一个迁移文件,我试图将其设置为内部类,将super重写为
super(Documents.UserDocFileField, self).__init__(*args, **kwargs)
但是,我得到了这个错误:
NameError: name 'Documents' is not defined
那么,有没有办法避免生成迁移文件,或者有更好的方法来解决此问题?
答案 0 :(得分:1)
一种实现方法是对upload_to
本身使用自定义类,并使用__call__
方法使实例可调用。为了使该序列化可移植,您需要添加一个deconstruct
方法。所以:
class UploadTo:
def __init__(self, name):
self.name = name
def __call__(self, instance, filename):
return 'documents/{}/{}.pdf'.format(instance.user.rfc, self.name)
def deconstruct(self):
return ('myapp.models.UploadTo', [self.fieldname], {})
class Documents(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
file_1 = FileField(upload_to=UploadTo('file_1'))
file_2 = FileField(upload_to=UploadTo('file_2'))
老实说,在这一点上,我可能只是为每个字段编写单独的upload_to
函数。