Как изменить имя загружаемого файла в Django? - PullRequest
28 голосов
/ 21 апреля 2010

Можно ли изменить имя загруженного файла в django? Я искал, но не мог найти ответ.

Мое требование: при загрузке файла его имя должно быть изменено в следующем формате.

format = userid + transaction_uuid + file_extension

Большое спасибо ...

Ответы [ 4 ]

48 голосов
/ 21 апреля 2010

Как вы загружаете файл? Я предполагаю с FileField.

В документации для FileField.upload_to указано, что поле upload_to,

также может быть вызываемым, например функция, которая будет вызываться получить путь загрузки, включая имя файла. Этот вызываемый должен уметь принять два аргумента и вернуть Путь в стиле Unix (с косой чертой) быть переданным на хранение система. Два аргумента, которые будут пройдено:

" instance ": экземпляр модель, в которой FileField определены. Более конкретно, это конкретный случай, когда текущий файл прикреплен.

" filename ": имя файла, которое было изначально передан в файл. Это может или не могут быть приняты во внимание, когда определение конечного пункта назначения путь.

Похоже, вам просто нужно создать функцию для обработки вашего имени и вернуть путь.

def update_filename(instance, filename):
    path = "upload/path/"
    format = instance.userid + instance.transaction_uuid + instance.file_extension
    return os.path.join(path, format)
6 голосов
/ 22 ноября 2013

Вам нужно иметь FileField с upload_to, который вызывает обратный вызов, см. [1]

Ваш обратный вызов должен вызывать метод-обертку, который получает экземпляр в качестве одного из параметров и имя файла в качестве другого. [2]

Измените его так, как вам нравится, и верните новый путь [3]

1. LOGIC

FileField(..., upload_to=method_call(params),....)

2. определить метод

def method_call(params):
    return u'abc'

3. Упаковочный:

def wrapper(instance, filename):
    return method

это метод рэпера, который вам нужен для получения экземпляра.

def wrapper(instance, filename):
... Your logic
...
return wrapper

Полный код

def path_and_rename(path, prefix):
    def wrapper(instance, filename):
        ext = filename.split('.')[-1]
        project = "pid_%s" % (instance.project.id,)
        # get filename
        if instance.pk:
            complaint_id = "cid_%s" % (instance.pk,)
            filename = '{}.{}.{}.{}'.format(prefix, project, complaint_id, ext)
        else:
            # set filename as random string
            random_id = "rid_%s" % (uuid4().hex,)
            filename = '{}.{}.{}.{}'.format(prefix, project, random_id, ext)
            # return the whole path to the file
        return os.path.join(path, filename)

    return wrapper

вызов метода

sales_attach = models.FileField("Attachment", upload_to=path_and_rename("complaint_files", 'sales'), max_length=500,
                                help_text="Browse a file")

Надеюсь, это поможет. Спасибо.

5 голосов
/ 11 февраля 2016

, если вы хотите, чтобы ваша функция использовалась повторно:

import hashlib
import datetime
import os
from functools import partial

def _update_filename(instance, filename, path):
    path = path

    filename = "..."

    return os.path.join(path, filename)

def upload_to(path):
    return partial(_update_filename, path=path)

Вы просто должны использовать это следующим образом:

document = models.FileField(upload_to=upload_to("my/path"))
1 голос
/ 22 октября 2018

Основной способ

import os

os.rename('a.txt', 'b.html')

Для вашей ситуации это, вероятно, будет выглядеть

os.rename ("a.txt", "{id}{uuid}.{ext}".format(id=userid, uuid=transaction_uuid, ext=file_extension))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...