Django在upload_to

时间:2018-10-15 17:52:22

标签: python django

我正在尝试为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

那么,有没有办法避免生成迁移文件,或者有更好的方法来解决此问题?

1 个答案:

答案 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函数。

相关问题