Jerry Bi
Jerry Bi

Reputation: 341

Preventing a file upload completely if file already exists in Django

I'm trying to make it so that when someone tries to upload a file that has already been uploaded before with a model form, the form will prevent it from submitting. Here is the relevant code:

models.py

class File(models.Model):
    file = models.FileField(upload_to='documents/')

forms.py

class FileForm(forms.ModelForm):
    file = forms.FileField()

    class Meta:
        model = File
        fields = ('file',)

views.py

def file_upload(request):
    if request.method == 'POST':
        form = FileForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return redirect('list_files')
        else:
            logger.error(form.errors)
    else:
        form = FileForm()

    return render(request, 'files/file_upload.html', {'form': form})

Let's say someone uploaded a file called document_1.xlsx. The way this code is now, if someone tries to upload another file called document_1.xlsx, it will upload it and add some weird suffix to it before the dot. I don't want that. I want the form to not allow anyone upload a file that already exists period, without breaking the code. Apparently adding 'unique=True' to the file field in the model doesn't work. I've seen so many questions that ask how to rename a file if it already exists, but I don't want that. I want to stop it completely if that file name already exists. Thanks.

EDIT:I don't believe this is a duplicate of another question. That question asks how to overwrite a file with the same name. This question is asking how to prevent a file with the same name from uploading.

Upvotes: 3

Views: 3572

Answers (2)

Julio
Julio

Reputation: 190

You can accomplish this on the clean method of your form. Just check on it whether there is a form with that name. If there is one, Raise a validation error. Something like: (I'm not 100% that this would work. But the solution is down this lines)

def clean_file(self):
    file = self.cleaned_data['file']
    if FileModel.objects.filter(file__name=file.name).exist():
        raise ValidationError('There is already a file with that name on our system')

Upvotes: 2

Hisagr
Hisagr

Reputation: 621

You need to override the default clean method for your form to add the logic of checking if file exists before saving.

Try the below in your FileForm class:

import os
from django.core.exceptions import ValidationError

def clean(self):
    file_path = "your folder/" + self.cleaned_data.get('file')
    if os.path.isfile(file_path):
        raise ValidationError('File already exists') 
    return self.cleaned_data

Upvotes: 1

Related Questions