Django将前缀添加到FileField

时间:2018-04-23 10:00:02

标签: django django-models

我有一个接收多个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子类化的错误方法吗?

2 个答案:

答案 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函数中包含这些参数。