Проверка файла CSV Django в чистом методе формы модели - PullRequest
0 голосов
/ 28 января 2019

Ниже приводится FileModel для загрузки файла CSV в мое приложение Django:

class File(models.Model):
  uploaded_by = models.ForeignKey(
    User,
    on_delete=models.CASCADE,
  )
  csv_file = models.FileField(
    upload_to='csvfiles/',
  )

При вызове шаблона URL /upload_file представление upload_csv_file выполняется следующим образом:

 def upload_csv_file(request):
   if request.method == 'POST':
      csv_form = CSVForm(request.POST, request.FILES)
      if csv_form.is_valid():
        file_uploaded = csv_form.save(commit=False)
        file_uploaded.uploaded_by = request.user
        csv_form.save()
        return HttpResponse("<h1>Your csv file was uploaded</h1>")

   elif request.method == 'GET':
      csv_form = CSVForm()
      return render(request, './mysite/upload_file.html', {'csv_form': csv_form})

В forms.py я проверяю следующее:

  • расширение файла (.csv)
  • размер файла (5 МБ)

    class CSVForm(forms.ModelForm):
    
      class Meta:
       model = File
       fields = ('csv_file',)
    
      def clean_csv_file(self):
       uploaded_csv_file = self.cleaned_data['csv_file']
    
       if uploaded_csv_file:
         filename = uploaded_csv_file.name
         if filename.endswith(settings.FILE_UPLOAD_TYPE):
            if uploaded_csv_file.size < int(settings.MAX_UPLOAD_SIZE):
                # return True
                  return uploaded_csv_file
            else:
                raise forms.ValidationError(
                    "Error")
        else:
            raise forms.ValidationError("Error")
    
      return uploaded_csv_file
    
      # no need for a separate def clean()
      # def clean(self):
        # cleaned_data = super(CSVForm, self).clean()
        # uploaded_csv_file = cleaned_data.get('csv_file')
        # return uploaded_csv_file
    

Однако при отправке кнопки загрузки файла возникает следующая ошибка:

  Attribute error: 'bool' object has no attribute 'get'

Я не уверен, вызывается ли def clean_csv_file(self) или нет.

Существуют способы проверки расширения и размера файла в функциональном представлении, но я хотел бы проверить атрибуты файла в самом методе clean() ModelForm.

ОБНОВЛЕНИЕ: найденное решение

def clean_csv_file (self) должен был возвращать экземпляр переменной uploaded_csv_file вместо True.

Кроме того, нет необходимости в методе clean (), если clean_field () присутствует вКласс ModelForm.

1 Ответ

0 голосов
/ 28 января 2019

Вы должны были показать полную ошибку и трассировку.

Тем не менее, ошибка вызвана тем, что вы возвращаете из clean_csv_file.Возвращаемым значением чистой функции всегда должны быть сами очищенные данные;для метода clean_field это должны быть очищенные данные для этого поля, а для общего метода clean это должен быть полный диалог cleaned_data.Итак:

def clean_csv_file(self):
   uploaded_csv_file = self.cleaned_data['csv_file']

   if uploaded_csv_file:
     filename = uploaded_csv_file.name
     if filename.endswith(settings.FILE_UPLOAD_TYPE):
        if uploaded_csv_file.size < int(settings.MAX_UPLOAD_SIZE):
            return uploaded_csv_file   # Here
        else:
            raise forms.ValidationError(
                "File size must not exceed 5 MB")
    else:
        raise forms.ValidationError("Please upload .csv extension files only")

  return uploaded_csv_file

Обратите внимание, ваш метод clean также неверен, но исправленная версия (которая возвращает cleaned_data) вообще ничего не делает, поэтому вы должны удалить всю вещь.

...