Как Django переименовывает загруженные файлы?

Если загрузить файл image.png из веб-браузера, новый файл с именем image.png появится в каталоге загрузки на сервере.

Если я затем загружу другой файл с именем image.png (то же имя), новый файл с именем image_aj642zm.png появится в каталоге загрузки на сервере.

Затем, если я загружу другой файл с именем image.png (снова то же имя), новый файл с именем image_z6z2BaQ.png появится в каталоге загрузки на сервере.

Какой метод использует Django для переименования загруженного файла, если файл с таким именем уже существует в каталоге загрузки? (т.е. откуда берутся лишние _aj642zm и _z6z2BaQ?)

Обычная установка:

В моделях.py:

from django.db import models

class Image(models.Model):
    image = models.ImageField(upload_to='uploads/')

В формах.py:

from django import forms
from .models import Image

class ImageForm(forms.ModelForm):
    class Meta:
        model = Image
        fields = ['image']

В представлениях.py:

from django.shortcuts import render, redirect
from .forms import ImageForm

def upload_image(request):
    if request.method == 'POST':
        form = ImageForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return redirect('index')
        else:
            form = ImageForm()

    return render(request, 'upload_file.html', {'form': form})

person Flux    schedule 15.02.2017    source источник
comment
Проверьте параметр upload_to в определении вашей модели.   -  person Bipul Jain    schedule 15.02.2017
comment
@BipulJain Аргумент upload_to указывает, куда поместить загруженный файл. Там ничего не сказано о схеме переименования. Может я что-то упускаю?   -  person Flux    schedule 15.02.2017
comment
Там можно указать метод. Что должно иметь переименование логики.   -  person Bipul Jain    schedule 15.02.2017
comment
Пожалуйста, поделитесь любым соответствующим кодом, который у вас есть. Насколько я знаю, Django не делает ничего подобного сам по себе.   -  person Chris    schedule 15.02.2017
comment
@Chris, на самом деле это делается по умолчанию внутри класса Storage, если имя такое же :)   -  person iklinac    schedule 15.02.2017
comment
@iklinac, правильно есть!   -  person Chris    schedule 15.02.2017
comment
@iklinac делает это в моем локальном хранилище, но, по-видимому, он отключен на моем рабочем сервере ... вы знаете, как его включить?   -  person Yokhen    schedule 05.12.2019


Ответы (1)


Метод класса хранилища Django по умолчанию называется получить_доступное_имя

    # If the filename already exists, add an underscore and a random 7
    # character alphanumeric string (before the file extension, if one
    # exists) to the filename until the generated filename doesn't exist.
    # Truncate original name if required, so the new filename does not
    # exceed the max_length.

Django по умолчанию сохраняет объект по его имени, но если объект с таким именем уже существует, добавляет подчеркивание и 7 случайных символов, как указано в комментарии к коду.

Кроме того, в дополнение к этому методу класса Django Storage get_valid_name анализирует имя файла ранее и заменяет все пробелы символами подчеркивания и удаляет все символы, которые не являются юникодом, альфа, тире, подчеркиванием или точкой.

re.sub(r'(?u)[^-\w.]', '', s)
person iklinac    schedule 15.02.2017
comment
как я могу включить это на моем рабочем сервере? почему-то там этого не делают. - person Yokhen; 05.12.2019