Django动态模型。FileField存储

时间:2018-11-08 15:24:51

标签: django django-models filefield

我有一个这样的模型:

class Person(models.Model):
    name = models.Charfield(max_length¶=30)
    photo = models.FileField(upload_to='uploads/')

是否有任何方法可以根据Storage字段的值动态更改photo字段的name类?

例如,我要将姓名为xxx的人的照片存储到FileSystemStorage¶,对于其他人,我想使用S3Storage

3 个答案:

答案 0 :(得分:0)

是的,您可以为某些特定文件分配自定义上传位置。

def my_upload_function(instance, filename):
    if instance.name === your_name:
        return your_location

    return generic_location


class Person(models.Model):
    name = models.Charfield(max_length¶=30)
    photo = models.FileField(upload_to=my_upload_function)

答案 1 :(得分:0)

听起来您需要创建一个自定义存储系统。官方文档讨论了如何执行此操作:https://docs.djangoproject.com/en/2.2/howto/custom-file-storage/

然后将您的存储系统传递到FileField:

photo = models.FileField(storage=MyStorage(),    # Make sure to instantiate with ()
                         upload_to='uploads/')

答案 2 :(得分:0)

我也有一个类似的用例。使用模型字段object_storage_name动态更新存储。 从文章https://medium.com/@hiteshgarg14/how-to-dynamically-select-storage-in-django-filefield-bc2e8f5883fd

中汲取灵感,在下面的代码中进行了尝试
class MediaDocument(models.Model):
    object_storage_name = models.CharField(max_length=255, null=True)
    file = DynamicStorageFileField(upload_to=mediadocument_directory_path)


class DynamicStorageFieldFile(FieldFile):

    def __init__(self, instance, field, name):
        super(DynamicStorageFieldFile, self).__init__(
            instance, field, name
        )
        if instance.object_storage_name == "alibaba OSS":
            self.storage = AlibabaStorage()
        else:
            self.storage = MediaStorage()


class DynamicStorageFileField(models.FileField):
    attr_class = DynamicStorageFieldFile

    def pre_save(self, model_instance, add):
        if model_instance.object_storage_name == "alibaba OSS":
            storage = AlibabaStorage()
        else:
            storage = MediaStorage()
        self.storage = storage
        model_instance.file.storage = storage
        file = super(DynamicStorageFileField, self
                     ).pre_save(model_instance, add)
        return file

效果很好。