1

I am using FileExtensionValidator Django's FileField and leverage this answer to limit the file size, both are working, but the validation error messages will not be shown.

I'm using Django 2.1. The following is my code:

Model

from django.core.validators import FileExtensionValidator

class Project(models.Model):
    owner = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='projects',
    )
    title = models.CharField(
        _('project name'),
        max_length=100,
        help_text=_('Required. 100 characters or fewer.'),
    )
    slug = models.SlugField(
        _('slug'),
        max_length=80,
    )
    created = models.DateTimeField(
        _('dateTime created'),
        auto_now_add=True,
    )
    xmlfile = models.FileField(
        _('input file'),
        upload_to=user_directory_path,
        validators=[FileExtensionValidator(allowed_extensions=('xml',))],
        help_text=_('Required. Please upload an XML file.'),
    )

Form

from django.core.exceptions import ValidationError

def file_size(value):
    limit = 9 * 1024 * 1024
    if value.size > limit:
        raise ValidationError('File too large. Size should not exceed 9 MiB.')

class ProjectForm(forms.ModelForm):

    xmlfile = forms.FileField(
        label='XML File Upload',
        widget=forms.FileInput(attrs={'accept':'application/xml'}),
        validators=[file_size],
    )

    class Meta:
        model = Project
        widgets = {
            'owner': HiddenInput(),
        }

View

class ProjectCreate(CreateView):
    form_class = ProjectForm
    model = Project
    template_name = 'project_new.html'
    success_url = reverse_lazy('my_projects_list')

    def get_initial(self):
        initial = super().get_initial()
        initial['owner'] = self.request.user
        return initial

I tested this code. When trying to upload an XML file less than 9M, it works and the user is brought to the success URL. But when either file format or file size is wrong, it's correct that we continue to stay on the page of project_new.html, but the strange thing is there is no error message displayed on this page related to FileExtensionValidator and file_size(). Do you know why? Where did I make mistake?

Thank you for your time and help!

student
  • 289
  • 2
  • 14

2 Answers2

1

I found the answer myself!

Originally, I was using {{ form|crispy }} in the template project_new.html . After I changed it to {{ form.as_p }}, the error information will be displayed on the screen.

Is this a bug of crispy_forms? How to make crispy_forms to show validation message for FileField?

student
  • 289
  • 2
  • 14
0

Try to create a function called clean_xmlfile inside the model form (ProjectForm), which will called automatically.

def clean_xmlfile(self, value):
    limit = 9 * 1024 * 1024
    if value.size > limit:
        raise ValidationError('File too large. Size should not exceed 9 MiB.')
Hari
  • 1,545
  • 1
  • 22
  • 45
  • This is not working. The website says Exception Type: AttributeError Exception Value: 'ProjectForm' object has no attribute 'size' – student Feb 25 '19 at 14:06
  • my bad, i forgot to pass self as first argument, now i updated the code – Hari Feb 25 '19 at 15:14
  • 1
    The real problem now I have is how to make the error message show up when using `{{ form|crispy }}`. See my own answer below! – student Feb 25 '19 at 18:22