Django validator not triggering on file upload

Question:

I have wrote a Django app for the user to upload files and see a list of uploaded files. I want to restrict the uploads to only using gif format and wrote a simple validator. Then I pass that validator in the Model, however it never triggers and the file is saved regardless of the format. Here’s what I got so far.

views.py

def list(request):
# Handle file upload
if request.method == 'POST':
    form = DocumentForm(request.POST, request.FILES)
    if form.is_valid():
        newdoc = Document(docfile=request.FILES['docfile'])
        newdoc.save()
        messages.add_message(request, messages.INFO, "Saved")

        # Redirect to the document list after POST
        return HttpResponseRedirect(reverse('list'))
else:
    form = DocumentForm()  # A empty, unbound form

# Load documents for the list page
documents = Document.objects.all()

# Render list page with the documents and the form
return render(
    request,
    'list.html',
    {'documents': documents, 'form': form}
)

checkformat.py

def validate_file_type(upload):
if not (upload.name[-4:] == '.gif'):
    raise ValidationError('File type not supported.')

models.py

from .checkformat import validate_file_type

def content_file_name(instance, filename):
     return '/'.join(['documents', str(filename), filename])

class Document(models.Model):
    docfile = models.FileField(upload_to=content_file_name, validators=[validate_file_type], null=False, verbose_name="File")

forms.py

class DocumentForm(forms.Form):
docfile = forms.FileField(
    label='Select a file', widget=forms.FileInput(attrs={'accept':'image/gif'})
)

Is there something I’m missing? I’ve just started learning Django. Also, I know this is not a sercure way to check for a file type, but I just want to see it work to continue. Thank you for your time.

Answers:

Looks right so far. Maybe it’s simply a lower/upper case issue?

A more accurate solution might be:

import os

def validate_file_type(upload):
    if os.path.splitext(upload.name)[1].lower() != '.gif':
        raise ValidationError('File type not supported.')

If it’s still not working try to add a break point within the validation method and check the value of upload.name.

Answered By: Tobias Lorenz
   if form.is_valid():
        newdoc = Document(docfile=request.FILES['docfile'])
        if not '.gif' in newdoc.name:
            raise ValidationError('File type not supported.')
        else:
            newdoc.save()
            messages.add_message(request, messages.INFO, "Saved")

try this simple solution, hope it works as you need

Answered By: Exprator

I think the problem is the form is derived from a simple Model class, but in your case you must use ModelForm instead.

This way the form knows about the Document model, and you can do some fancy operations, like calling the save mehond in the Form object so save the model instance. Also the is_valid method calls all the validations defined in the model, in addition to the validations defined in the Form itself.

Answered By: Dayana
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.