2017-05-10 4 views
0

J'ai mis en place un formulaire et une vue pour télécharger plusieurs fichiers * .gpx sur mon site Web en même temps. Ces fichiers sont validés à l'aide d'une méthode clean() sur le formulaire puis, une fois validés, transmis à une fonction pour traitement.La méthode clean() provoque la perte de données des fichiers à l'aide du formulaire POST

Lorsque je télécharge des fichiers non valides, la méthode clean() les attrape et informe l'utilisateur comme prévu.

Lorsque je télécharge des fichiers valides, la fonction de traitement se bloque avec une erreur indiquant que les fichiers sont vides.

Si je commente la méthode clean() alors les fichiers valides sont bien téléchargés.

Que peut-il arriver au formulaire pendant la méthode clean() que signifie que les fichiers sont supprimés?

ici est ma forme:

class UploadGpxForm(forms.Form): 

    gpx_file = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True})) 

voici mon avis:

class UploadGpxView(FormView): 
    form_class = UploadGpxForm 
    template_name = 'dashboard/upload.html' # Replace with your template. 
    success_url = reverse_lazy('dashboard:index') # Replace with your URL or reverse(). 

    def post(self, request, *args, **kwargs): 
     form_class = self.get_form_class() 
     form = self.get_form(form_class) 
     files = request.FILES.getlist('gpx_file') 
     if form.is_valid(): 
      for f in files: 
       SaveGPXtoPostGIS(f) 
      return self.form_valid(form) 
     else: 
      return self.form_invalid(form) 

Voici ma méthode propre pour la UploadGpxForm:

def clean(self): 

     file_errors=[] 

     files = list(self.files.getlist('gpx_file')) 

     for f in list(files): 
      #check file has only one full stop in it. 
      if len(f.name.split('.')) != 2: 
       file_errors.append(ValidationError(
        _('%(file_name)s has not been uploaded:'\ 
        'File type is not supported') 
        , params = { 'file_name': f.name } 
        , code = 'file_type') 
        ) 

      #check file doesn't breach the file size listed in settings 
      if f.content_type in settings.DASHBOARD_UPLOAD_FILE_TYPES: 
       if f._size > settings.DASHBOARD_UPLOAD_FILE_MAX_SIZE: 
        file_errors.append(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': f.name, 
          'setting_size': filesizeformat(
           settings.DASHBOARD_UPLOAD_FILE_MAX_SIZE), 
          'file_size': filesizeformat(f._size) 
          }, 
         code = 'file_size' 
          ) 
          ) 
      #check it is one of our allowed file types 
      else: 
       file_errors.append(ValidationError(
        _('%(file_name)s has not been uploaded:'\ 
        'File type is not supported') 
        , params = { 'file_name' : f.name } 
        , code = 'file_type' 
        ) 
        ) 
      #next check the file hasn't been uploaded before 
      #generate MD5 
      md5hash = md5() 
      for chunk in f.chunks(): 
       md5hash.update(chunk) 
      file_hash = md5hash.hexdigest() 

      if gpxTrack.objects.filter(file_hash=file_hash).exists(): 
       file_errors.append(ValidationError(
        _('%(file_name)s has not been uploaded as a identical file'\ 
        'has already been uploaded previously'), 
        params = { 'file_name' : f.name }, 
        code = 'file_hash')) 

     #finally raise errors if there are any 
     if len(file_errors) > 0: 
      raise ValidationError(file_errors) 
     else: 
      return files 
+0

Considérez encore réduire votre problème (et question) et fournir des données de l'échantillon: https://stackoverflow.com/help/mcve – handle

Répondre

1

Quand vous lisez le contenu du fichier (pour calculer le hachage md5) vous devez déplacer la position de l'objet fichier au début (octet 0) en utilisant file.seek:

md5hash = md5() 
for chunk in f.chunks(): 
    md5hash.update(chunk) 
file_hash = md5hash.hexdigest() 
f.seek(0) #<-- add this line 
+0

Merci beaucoup, je l'ai essayé d'obtenir que cela fonctionne pour âge. ça a fonctionné parfaitement. – Domronic