Метод get_available_name
Метод get_available_name применяется к объекту хранилища
и возвращает имя файла, которое не конфликтует с существующими
файлами в хранилище. Если файл с переданным именем уже существует,
метод генерирует новое уникальное имя. Это особенно полезно при
загрузке пользовательских файлов, чтобы избежать перезаписи
существующих файлов. Метод принимает имя файла и опционально
максимальное количество попыток генерации уникального имени.
Синтаксис
storage.get_available_name(name, max_length=None)
Параметры метода:
-
name- имя файла, для которого нужно найти доступное имя -
max_length- максимальная длина имени файла, опциональный параметр
Пример . Использование с хранилищем по умолчанию
Рассмотрим базовый пример использования метода get_available_name
с хранилищем по умолчанию:
from django.core.files.storage import default_storage
# Проверяем доступное имя для файла
available_name = default_storage.get_available_name('documents/file.txt')
print(available_name)
Результат выполнения кода:
"documents/file.txt"
Если файл уже существует, метод автоматически добавляет суффикс к имени:
from django.core.files.storage import default_storage
# Создаем файл для демонстрации
default_storage.save('documents/file.txt', b'content')
# Пытаемся получить доступное имя для существующего файла
available_name = default_storage.get_available_name('documents/file.txt')
print(available_name)
Результат выполнения кода:
"documents/file_1.txt"
Пример . С ограничением длины имени
Рассмотрим пример использования метода с указанием максимальной длины имени файла:
from django.core.files.storage import default_storage
# Получаем доступное имя с ограничением длины
long_name = 'very_long_filename_that_exceeds_max_length.txt'
available_name = default_storage.get_available_name(
long_name,
max_length=20
)
print(available_name)
Результат выполнения кода:
"very_long_filen_1.txt"
Пример . Использование в модели
Рассмотрим пример использования метода get_available_name
при сохранении файлов в модели:
from django.db import models
from django.core.files.storage import default_storage
class Document(models.Model):
name = models.CharField(max_length=100)
file = models.FileField(upload_to='documents/')
def save(self, *args, **kwargs):
if self.file:
# Получаем доступное имя для файла
available_name = default_storage.get_available_name(
self.file.name
)
# Сохраняем файл с уникальным именем
self.file.name = available_name
super().save(*args, **kwargs)
Теперь при сохранении модели файл всегда будет иметь уникальное имя, что предотвращает перезапись существующих файлов:
from myapp.models import Document
# Создаем первый документ
doc1 = Document.objects.create(
name='First Document',
file='documents/example.txt'
)
print(doc1.file.name)
# Создаем второй документ с тем же именем файла
doc2 = Document.objects.create(
name='Second Document',
file='documents/example.txt'
)
print(doc2.file.name)
Результат выполнения кода:
"documents/example.txt"
"documents/example_1.txt"
Пример . С кастомным хранилищем
Метод get_available_name может быть переопределен
в пользовательском классе хранилища для изменения логики
генерации уникальных имен:
from django.core.files.storage import FileSystemStorage
import os
import time
class TimestampStorage(FileSystemStorage):
def get_available_name(self, name, max_length=None):
# Проверяем существование файла
if self.exists(name):
# Генерируем имя с временной меткой
dir_name, file_name = os.path.split(name)
name_parts = os.path.splitext(file_name)
timestamp = int(time.time())
new_name = f"{name_parts[0]}_{timestamp}{name_parts[1]}"
return os.path.join(dir_name, new_name)
return name
# Использование кастомного хранилища
storage = TimestampStorage()
available_name = storage.get_available_name('documents/file.txt')
print(available_name)
Результат выполнения кода:
"documents/file_1234567890.txt"
Смотрите также
-
метод
save,
который сохраняет файл в хранилище -
метод
exists,
который проверяет существование файла в хранилище -
метод
get_valid_filename,
который возвращает корректное имя файла -
класс
FileSystemStorage,
который реализует файловое хранилище