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:
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")