如何创建一个 upload_to 文件夹,该文件夹名为属于同时创建的模型的字段?

问题描述 投票:0回答:3

上下文:我正在使用 Django 3.1.4 构建一个汽车经销商应用程序,并尝试实现一个功能,每次创建新广告时,/media/ 中都会创建一个新文件夹(通过 upload_to 方法)仅包含新创建的广告的照片。

我已经使用日期格式(见下文)来完成这项工作,但我需要将这个新文件夹命名为属于模型的字段之一(请参阅第二个代码片段)。

photo_4 = models.ImageField(upload_to='photos/%Y/%m/%d', blank=True)

例如,每个新创建的广告都会使用标题字段..

class Vehicles(models.Model):
    CONDITION_CHOICES = [("Brand New","Brand New"),("Used", "Used")]
    FUEL_CHOICES = [("Petrol","Petrol"),("Diesel", "Diesel"),("Electric", "Electric"),("Hybrid", "Hybrid")]
    TRANSMISSION_CHOICES = [("Automatic","Automatic"),("Manual", "Manual")]
    title = models.CharField(max_length=200, default = "Ad Title & Folder Name")
    def folder_name(self, title):
        return self.title
    make = models.CharField(max_length=100)

理想情况下,媒体文件夹看起来像这样

/media/
    Opel Astra VXR/
    Mercedes E200/

我知道许多其他人也做了类似的事情,但我发现的所有示例都使用“用户”,而我需要使用模型字段(属于正在创建的模型)作为文件夹名称。

结束语: 第二个代码片段中的功能只是我正在尝试的功能。

此外,这仍在开发中,因此在产品中我完全打算将所有媒体直接定向到 S3 存储桶。

python-3.x django django-models file-upload dynamic-programming
3个回答
3
投票

记录

upload_to 也可以是可调用的,例如函数。这将是 调用以获取上传路径,包括文件名。这 callable 必须接受两个参数并返回 Unix 风格的路径(带有 正斜杠)将被传递到存储系统。两人 论据是:

  • 实例(定义 FileField 的模型实例。)
  • 文件名(最初赋予文件的文件名)

例如:

def user_directory_path(instance, filename):
    # file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
    return 'user_{0}/{1}'.format(instance.user.id, filename)

2
投票

找到解决方案并想将其发布给下一个可能需要它的人。事实证明这是我的格式的语法问题。这成功了,现在为每个广告及其照片打开一个新文件夹。它还会使用添加到预先存在的广告中的任何新照片来更新原始文件夹。

标题和功能如下:

title = models.CharField(max_length=200, default = "Ad Title & Folder Name")
    def upload_photo_to(self, filename):
        return f'{self.title}/{filename}'

照片领域及其应用方式:

photo_1 = models.ImageField(upload_to=upload_photo_to, blank=True)

0
投票

我也遇到过类似的情况。但是,我希望我的文件路径在路径中包含应用程序名称和模型名称。我的解决方案如下:

class mymodel(models.Model):
    def get_media_path(self, filename):
       return f'{self._meta.app_label}/{self._meta.object_name}/{filename}'
    myfile = models.ImageField(upload_to=get_media_path)

对于您的场景,我们假设 mymodel 有一个名为 car_model 的字段。所以你的实现就像:

class mymodel(models.Model):
    def get_media_path(self, filename):
       return f'{self.car_model}/{filename}'
    car_model = models.CharField(max_length=255)
    myfile = models.ImageField(upload_to=get_media_path)
© www.soinside.com 2019 - 2024. All rights reserved.