44

モデル 'Products' を保存するときに、アップロードされた画像に pk と同じ名前を付けたいと思います。たとえば、22.png や 34.gif などです。これはどのように行うことができますか?これまでの私のモデルの例...

image = models.ImageField(
        upload_to="profiles",
        height_field="image_height",
        width_field="image_width",
        null=True,
        blank=True,
        editable=True,
        help_text="Profile Picture",
        verbose_name="Profile Picture"
    )
    image_height = models.PositiveIntegerField(null=True, blank=True, editable=False, default="100")
    image_width = models.PositiveIntegerField(null=True, blank=True, editable=False, default="100")
4

6 に答える 6

93

関数をupload_toフィールドに渡すことができます:

def f(instance, filename):
    ext = filename.split('.')[-1]
    if instance.pk:
        return '{}.{}'.format(instance.pk, ext)
    else:
        pass
        # do something if pk is not there yet

私の提案は、の代わりにランダムなファイル名を返すことです{pk}.{ext}。おまけとして、より安全になります。

Django はこの関数を呼び出して、ファイルのアップロード先を決定します。これは、関数がファイル名を含むファイルのパス全体を返す責任があることを意味します。以下は、アップロード先と使用方法を指定できる変更された関数です。

import os
from uuid import uuid4

def path_and_rename(path):
    def wrapper(instance, filename):
        ext = filename.split('.')[-1]
        # get filename
        if instance.pk:
            filename = '{}.{}'.format(instance.pk, ext)
        else:
            # set filename as random string
            filename = '{}.{}'.format(uuid4().hex, ext)
        # return the whole path to the file
        return os.path.join(path, filename)
    return wrapper

FileField(upload_to=path_and_rename('upload/here/'), ...)
于 2013-02-28T16:56:05.820 に答える
30

Django 1.7 以降では、このような機能を使用した移行は行われません。@ miki725 の回答とこのチケットに基づいて、関数を次のようにする必要があります。

import os
from uuid import uuid4
from django.utils.deconstruct import deconstructible

@deconstructible
class UploadToPathAndRename(object):

    def __init__(self, path):
        self.sub_path = path

    def __call__(self, instance, filename):
        ext = filename.split('.')[-1]
        # get filename
        if instance.pk:
            filename = '{}.{}'.format(instance.pk, ext)
        else:
            # set filename as random string
            filename = '{}.{}'.format(uuid4().hex, ext)
        # return the whole path to the file
        return os.path.join(self.sub_path, filename)

FileField(upload_to=UploadToPathAndRename(os.path.join(MEDIA_ROOT, 'upload', 'here'), ...)
于 2015-12-01T14:22:16.220 に答える
7

docsupload_toで説明されているように、割り当てた文字列を callableに置き換えることができます。ただし、パラメーターが使用される時点で主キーが使用できない可能性があると思われます。upload_to

于 2013-02-28T16:53:14.040 に答える
1

別のオプションとして、この回答https://stackoverflow.com/a/15141228/3445802に従うと、リターンパスが必要なときに問題が見つかりました%Y/%m/%d。例:

FileField(upload_to=path_and_rename('upload/here/%Y/%m/%d'), ...)

したがって、次のように処理します。

FileField(upload_to=path_and_rename('upload/here/{}'.format(time.strftime("%Y/%m/%d"))), ...)

モジュールtimeがインポートされていることを確認します。

于 2016-04-26T13:18:45.113 に答える