Начальная настройка
Несколько полей в модели MyModel
хранят файлы:
class MyModel(models.Model):
icon2x = models.ImageField(...)
logo2x = models.ImageField(...)
По умолчанию Django
перезаписывает имена файлов во время загрузки и применяет имя поля с необязательное случайное приложение, если файл с таким именем уже существует в storage
.
Например, если мы сохраним два экземпляра MyModel
с файлом image.png
в поле icon2x
для очистки базы данных и storage
:
- Первый экземпляр
MyModel
сохранит файл в поле icon2x
с именем icon2x.png
. - Второй экземпляр
MyModel
должен будет приспособиться к уже существующему файлу icon2x.png
в storage
и применить к имени случайное приложение, которое может выглядеть примерно как icon2x_AFtv0jG.png
Если по какой-то причине желательно получить имя файла, хранящегося в поле без рандомизированного приложения, следующая реализация отлично справится с задачей:
def strip_name(field):
name, extension = os.path.splitext(os.path.basename(field.name))
full_name = name.split('_')[0] + extension
return full_name
Объяснение кейса
Файлы поля, хранящиеся в icon2x
и logo2x
, впоследствии используются в качестве содержимого zip-архивов.
Для правильного импорта архива в другую систему имена файлов должны соответствовать строгой политике именования, которая требует определенного формата. Этот формат содержит символы, несовместимые с синтаксисом Python: например, файл значка должен иметь имя icon@2x.png
.
Из-за символа @
невозможно изменить имя поля на icon@2x
и logo@2x
чтобы имя каждого файла, хранящегося в этих полях, соответствовало политике именования архивов (после применения strip_name
метода)
Что было предпринято до сих пор
Я пытался явно указать имя поле в определении поля:
...
icon2x = models.ImageField(name='icon@2x', ...)
...
Но это не изменило способ Django
именованных файлов, сохраненных в этом поле и сделавших поле недоступным по ссылке my_model_instance.icon2x
.
Вопрос
Учитывая, как Django
присваивает имена файлам, как определить базовое имя файла, хранящегося в FileField
?
Потенциальные решения, которые могут решить эта проблема, но я не знаю, как достичь любой из них:
Потенциальный вариант 1 (идеальное решение): переопределить метод поля или атрибут на основе "для поля", который является тавленные Присвоить имя файла в процессе загрузки для storage
.
Потенциальная опция 2: переопределить имя файла во время поиска.
Таким образом, фактическое имя файла, хранящегося в FileField
, не имеет значения, если его можно переопределить, когда на атрибуты полей name
ссылаются some_field.name
.
Потенциальный вариант 3 (я бы предпочел этого избежать): пользовательская Field
реализация, полученная из FileField
.