Как изменить шаблон переименования при наличии дубликатов файлов

Допустим, я загружаю файл в мое приложение Django (A.pdf)

Со временем я понимаю, что этот файл содержит ошибку. Я хочу загрузить этот файл обратно на свой сайт и сохранить старый файл, но я хочу, чтобы имя файла изменилось на A(1).pdf

Я реализовал систему drag & drop с помощью Dropzone.js и все работает, но при дублировании файла система присваивает новые имена случайным образом.

Вот пример:

enter image description here enter image description here

Как избавиться от строки _QXjmarl и заменить ее шаблоном (N)? E.g. (1), (2), (3)...(45), (N)

Dropzone.js:

var Drop = Dropzone.options.DidDropzone = {

    autoProcessQueue: false, //stops from uploading files until user submits form
    paramName: "filename", // The name that will be used to transfer the file
    maxFilesize: 1024, // Maximum size of file that you will allow (MB)
    clickable: true, // This allows the dropzone to select images onclick
    acceptedFiles: '.psd, .csv, .doc, .docx, .xls, .xlsx, application/csv, application/docx, application/excel, application/msword, application/pdf,application/vnd.ms-excel, application/vnd.msexcel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, text/anytext, text/comma-separated-values, text/csv, text/plain, image/*, video/*,', //accepted file types
    maxFiles: 20, //Maximum number of files/images in dropzone
    parallelUploads: 20,
    previewTemplate: '<div class="dz-preview dz-image-preview">'+
                        '<div class="dz-image">'+
                        '<img data-dz-thumbnail />'+
                        '</div>'+

                      '<div class="dz-details">'+
                        '<div class="dz-filename"><span data-dz-name></span></div>'+
                        '<div class="dz-size" data-dz-size></div>'+
                      '</div>'+

                      '<div class="dz-success-mark"><span>✔</span></div>'+
                      '<div class="dz-error-mark"><span>✘</span></div>'+
                      '<div class="dz-error-message"><span data-dz-errormessage></span></div>'+
                    '</div>',
    init: function(){

        var submitButton = document.querySelector("#image-btn")
        var url = $('#DidDropzone').attr("action")
        myDropzone = this;

        //process the queued images on click
        submitButton.addEventListener("click", function() {
            myDropzone.processQueue();
            $('#fileUploadModal').modal('hide'); 
        });

        //fire the images to url
        myDropzone.on("processing", function(file) {
          myDropzone.options.url = url;
        });

        //clear the dropzone when complete
        myDropzone.on("complete", function(file) {
            myDropzone.removeFile(file);
        });
    },
    success: function(file, json){

        // alert("Perfect! Now visit your gallery...")      
        
    },
}

views.py:

@login_required
def project_page(request):
    context = {}
    context['nbar'] = projects
    if request.method == 'POST':
        print(request.FILES)
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            file_hist = form.save(commit=False)
            file_hist.user = request.user
            file_hist.save()
            return render(request, 'project_page.html', context)
    else:
        form = UploadFileForm()
    context['form'] = form
    return render(request, 'project_page.html', context)

project_page.html:

<form action="project_page" id="DidDropzone" class="dropzone dz" accept-charset="UTF-8" method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    <svg class="col-12 text-center" xmlns="http://www.w3.org/2000/svg" width="64" height="64" fill="#193D4C" class="bi bi-download" viewBox="0 0 16 16">
        <path d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z"/>
        <path d="M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3z"/>
    </svg>
    <div class="dz-message">
        <div class="dz-message2">Choose files</div>
        or drag them here.
    </div>
</form>

Есть ли в Django предопределенный метод для изменения шаблона дубликатов файлов? Я не нашел ничего в интернете и не знаю, какая часть кода переименовывает файлы.

Какой самый питонический способ достижения желаемого результата?

Вы можете написать свой собственный класс хранилища и переписать метод get_alternative_name, чтобы изменить это поведение

from django.core.files.storage import FileSystemStorage


class MyStorage(FileSystemStorage):

    def get_alternative_name(self, file_root, file_ext):
        n = get_next_n(file_root)  # Needs to be implemented
        return f'{file_root}({n}){file_ext}'

Затем добавьте установку

DEFAULT_FILE_STORAGE = 'my_app.storage.MyStorage'
Вернуться на верх