我有一个接收多个pdf文件的模型。当用户上传这些文件时,我希望用前缀和一些随机字符重命名每个文件。我可以将upload_to分配给可调用函数,例如:
class Order(models.Model):
invoice_file = models.FileField(upload_to=invoice_file_name)
purchase_order_file = models.FileField( upload_to=po_file_name)
payment_file = models.FileField( upload_to=payment_file_name)
def invoice_file_name(instance, file_name):
return 'inv_' + str(uuid.uuid4()) + '.pdf'
def po_file_name(instance, file_name):
return 'po_' + str(uuid.uuid4()) + '.pdf'
def payment_file_name(instance, file_name):
return 'pmt_' + str(uuid.uuid4()) + '.pdf'
有没有办法概括这些upload_to函数,以便我可以在FileField定义中传递前缀?
ATTEMPT:
我尝试通过创建扩展FileField
的自定义文件字段来解决此问题class CustomFileField(models.FileField):
def __init__(self, file_prefix, **kwargs):
self.file_prefix = file_prefix
# print(kwargs)
super().__init__(upload_to=self.custom_upload_to, **kwargs)
def custom_upload_to(self, file_name):
return self.file_prefix + str(uuid.uuid4()) + '.pdf'
class Order(models.Model):
invoice_file = CustomFileField(file_prefix='inv_')
purchase_order_file = CustomFileField(file_prefix='po_')
payment_file = CustomFileField(file_prefix='pmt_')
但是,迁移失败了。其中一个错误是
TypeError: __init__() got multiple values for keyword argument 'upload_to'
不太确定发生了什么,但我查看了迁移文件,似乎在调用它:
migrations.CreateModel(
name='Order',
fields=[
('invoice_file', CustomFileField(blank=True, null=True, upload_to='')
...
])
这是将FileField子类化的错误方法吗?
答案 0 :(得分:1)
您可以不使用 A a = new A(true,false);//this given error as there are four input value
A a = new A(true,false,true,false);//this will work
而是使用CustomFileField
@deconstructible
实例,在调用from django.utils.deconstruct import deconstructible
from django.db import models
@deconstructible
class file_prefix(object):
def __init__(self, prefix):
self.prefix = prefix
def __call__(self, instance, filename):
ext = filename.split('.')[-1] # PDF if you want
filename = "%s%s.%s" % (self.prefix,str(uuid.uuid4()), ext)
return filename
时默认发送文件名,因此我们只发送前缀。
upload_to
答案 1 :(得分:0)
这是有效的:
class CustomFileField(models.FileField):
def __init__(self, file_prefix = '', null=True, blank=True, upload_to='', **kwargs):
self.file_prefix = file_prefix
super().__init__(upload_to=self.custom_upload_to, **kwargs)
def custom_upload_to(self, instance, file_name):
return self.file_prefix + str(uuid.uuid4()) + '.pdf'
class Order(models.Model):
invoice_file = CustomFileField(file_prefix='inv_')
purchase_order_file = CustomFileField(file_prefix='po_')
payment_file = CustomFileField(file_prefix='pmt_')
迁移序列化程序似乎查找3个参数:null,blank和upload_to,因此我需要在CustomFileField init函数中包含这些参数。