2

I am currently trying to create a Django app that allows a user to upload multiple .gpx files at once. I would like that when the files are validated the user is provided with a list of files and the reason they weren't uploaded.

The file is validated by the following:

  • File size
  • File type
  • Has this file been uploaded before (based on hash of file)
  • If the user uploads a single file that fails any of the above they get the correct error message. If they upload 2 or more files which have an error they only get the message for the first error that occurs.

    here is my form.py:

    from django import forms
    
    from .validators import validate_file
    
    class UploadGpxForm(forms.Form):
        gpx_file = forms.FileField(widget=forms.ClearableFileInput(
            attrs={'multiple': True}), 
            validators=[validate_file]
            )
    

    here is my validators.py:

    from hashlib import md5
    
    from .models import gpxTrack
    
    from django.conf import settings
    from django.template.defaultfilters import filesizeformat
    from django.core.exceptions import ValidationError
    from django.utils.translation import ugettext_lazy as _
    
    def validate_file(value):
        if len(value.name.split('.')) != 2:
            raise ValidationError(
                _('%(file_name)s has not been uploaded: File type is not supported') 
                , params = { 'file_name': value.name }
                , code = 'file_type'
                )
        if value.content_type in settings.DASHBOARD_UPLOAD_FILE_TYPES:
            if value._size > settings.DASHBOARD_UPLOAD_FILE_MAX_SIZE:
                raise ValidationError(
                    _('%(file_name)s has not been uploaded: File too big.'\
                    'Please keep filesize under %(setting_size)s.'\
                    'Current filesize %(file_size)s') ,
                    params = { 
                        'file_name': value.name,
                        'setting_size': filesizeformat(settings.DASHBOARD_UPLOAD_FILE_MAX_SIZE),
                        'file_size': filesizeformat(value._size)
                        },
                    code = 'file_size'
                        )
        else:
            raise ValidationError(
                _('%(file_name)s has not been uploaded: File type is not supported')
                 , params = { 'file_name' : value.name }
                 , code = 'file_type'
                 )
    
    
        #generate MD5
        md5hash = md5()
        for chunk in value.chunks():
            md5hash.update(chunk)
        file_hash = md5hash.hexdigest()
        if gpxTrack.objects.filter(file_hash=file_hash).exists():
            raise ValidationError(_('%s has already been uploaded') % (value.name))
    

    Here's my model.py:

    from django.contrib.gis.db import models
    from django.contrib.gis import admin as geoadmin
    
    class gpxTrack(models.Model):
    
        class Meta:
            ordering = ['-start']
    
        track = models.MultiLineStringField()
        file_hash = models.CharField("md5 hash value", max_length=32, unique=True)
        start = models.DateTimeField("Start date and time", blank=True, null=True)
        objects = models.GeoManager()
    
        def __str__(self):
            return self.start.strftime("%a %p %-d %B %Y")
    
    Domronic
    • 149
    • 1
    • 1
    • 11
    • What exactly are you asking for help on? Does something in the code you provide not work? – themanatuf May 08 '17 at 15:27
    • Sorry for the unclear question. I'm looking to try get a list of files that haven't passed validation and then pass that to the user. – Domronic May 08 '17 at 17:00
    • Can you try implementing a `clean` function rather than assigning `validators`? With the `clean` function you'll be able to loop through the files individually and raise multiple errors: https://docs.djangoproject.com/en/1.11/ref/forms/validation/#raising-multiple-errors – themanatuf May 08 '17 at 17:26
    • Thanks, that does seem easier. So I just create a list with lots of ValidationError tuples and then pass that to a ValidationError that I actually raise? – Domronic May 08 '17 at 17:36

    0 Answers0