2

I have probelem when I submit the file to the django server and the name of the file exist in a directory. Django do not override the file, but it add some characters to the end of the name. How can I add characters instead of Django.

My model.py looks like this

class UpLoadFile(models.Model):
      user = models.ForeignKey(User, on_delete=models.CASCADE)
      file = models.FileField()
      uploaded_at = models.DateTimeField(default=timezone.now)

      def __str__(self):
          return self.file.name + ' (' + self.user.username + ')'

views.py looks like this:

@login_required
def home(request):
    if request.method == 'POST':

        if 'upload_file' in request.POST:
            form = UploadFileForm(request.POST, request.FILES)
            form.instance.user = request.user
            if form.is_valid():
                messages.success(request, 'Datoteka {} je bila uspešno dodana'.format(str(request.FILES["file"])))
                form.save()
                return HttpResponseRedirect('/')

        else:
            messages.error(request, 'Datoteke {} ni bilo mogoče dodati. Preveriti če datoteka vsebuje podatke.'
                           .format(str(request.FILES["file"])))
            return HttpResponseRedirect('/')


    elif request.method == 'GET':
        upload_file = UploadFileForm()
        return render(request, 'update_file/home.html', {'page_title': 'Home', 'upload_form': upload_file})

forms.py looks like this:

class UploadFileForm(forms.ModelForm):
    file = forms.FileField(required=True)

    class Meta:
        model = UpLoadFile
        fields = ('file',)
Mihael Waschl
  • 330
  • 1
  • 6
  • 19
  • Take a look at [file storages](https://docs.djangoproject.com/en/2.1/ref/files/storage/) in django, and e.g. this [question](https://stackoverflow.com/questions/9522759/imagefield-overwrite-image-file-with-same-name). – mfrackowiak Feb 26 '19 at 13:51
  • So if a file already exists, you want to keep that file (don't overwrite) and append your own set of characters to the name of the uploaded file? – Will Keeling Feb 27 '19 at 11:57
  • @WillKeeling Yes. – Mihael Waschl Feb 28 '19 at 12:10

1 Answers1

5

The default behaviour of Django's Storage class is to append a series of random characters to the end of the filename when the filename already exists. If you wish to control what characters are appended, you can create your own Storage sub-class and override the get_available_name() function.

A very simple example which appends a fixed set of characters to the end of the name (you might want to adapt to vary the characters):

import os
from django.core.files.storage import FileSystemStorage

class MyStorage(FileSystemStorage):

    def get_available_name(self, name, max_length=None):
        if self.exists(name):
            dir_name, file_name = os.path.split(name)
            file_root, file_ext = os.path.splitext(file_name)            

            my_chars = 'abcde'  # The characters you want to append

            name = os.path.join(dir_name, '{}_{}{}'.format(file_root, my_chars, file_ext))
        return name

You can then specify the custom storage class on the model:

class UpLoadFile(models.Model):
      user = models.ForeignKey(User, on_delete=models.CASCADE)
      file = models.FileField(storage=MyStorage())  # Your custom storage
      ...

Also worth looking at the existing code for Django's get_available_name().

Will Keeling
  • 22,055
  • 4
  • 51
  • 61