Django中的动态文件路径

iva*_*123 45 django django-models

我正在尝试在django中生成动态文件路径.我想创建一个这样的文件系统:

 -- user_12
     --- photo_1
     --- photo_2
 --- user_ 13
     ---- photo_1
Run Code Online (Sandbox Code Playgroud)

我发现了一个相关的问题:Django自定义图像上传字段,带有动态路径

在这里,他们说我们可以更改upload_to路径并转到https://docs.djangoproject.com/en/stable/topics/files/doc.在文档中,有一个例子:

from django.db import models
from django.core.files.storage import FileSystemStorage

fs = FileSystemStorage(location='/media/photos')

class Car(models.Model):
    ...
    photo = models.ImageField(storage=fs)
Run Code Online (Sandbox Code Playgroud)

但是,这仍然不是动态的,我想将Car id赋予图像名称,并且在Car定义完成之前我无法分配id.那么如何创建一个带有车牌ID的路径?

DrM*_*ers 70

您可以在upload_to参数中使用callable,而不是使用自定义存储.请参阅文档,并注意那里的警告,即在调用函数时可能尚未设置主键(因为可以在将对象保存到数据库之前处理上载),因此ID可能无法使用.您可能会考虑在模型上使用另一个字段,例如slug.例如:

import os
def get_upload_path(instance, filename):
    return os.path.join(
      "user_%d" % instance.owner.id, "car_%s" % instance.slug, filename)
Run Code Online (Sandbox Code Playgroud)

然后:

photo = models.ImageField(upload_to=get_upload_path)
Run Code Online (Sandbox Code Playgroud)

  • @MatthieuRiegler你错了.它适用于我刚刚测试过的Django 1.5.5. (3认同)
  • 请参阅答案中的"docs"链接.它卖给你 - "将要通过的两个论点是......" (2认同)

Yuj*_*ita 6

https://docs.djangoproject.com/en/stable/ref/models/fields/#django.db.models.FileField.upload_to

def upload_path_handler(instance, filename):
    return "user_{id}/{file}".format(id=instance.user.id, file=filename)

class Car(models.Model):
    ...
    photo = models.ImageField(upload_to=upload_path_handler, storage=fs)
Run Code Online (Sandbox Code Playgroud)

文档中有一个警告,但它不应该影响你,因为我们是在UserID而不是CarID之后.

在大多数情况下,此对象尚未保存到数据库,因此如果它使用默认的AutoField,则它可能还没有其主键字段的值.

  • 除非你阅读`FileField`上的所有文档,否则有一点可能并不完全明显,即`upload_to`可调用实际上会返回一个文件名`/ path/to/base.ext`,它会附加到你的存储位置.因为存储抽象了绝对路径和文件操作,所以不太明显的好处是您可以将文件移动到完全不同的存储/位置,并且模型将继续按预期工作. (2认同)

Jam*_*Lin 6

您可以使用如下 lambda 函数,请注意,如果实例是新的,则它不会有实例 ID,因此请使用其他内容:

logo = models.ImageField(upload_to=lambda instance, filename: 'directory/images/{0}/{1}'.format(instance.owner.id, filename))
Run Code Online (Sandbox Code Playgroud)

  • django 无法序列化 lambda,所以这个答案现在已经过时了 (3认同)