Django form.is_valid() не возвращает файл
Я пытаюсь проверить загрузку CSV-файла, проверяя наличие всех ожидаемых заголовков. После того, как я прохожу валидацию на моей форме, возвращаемый файл, похоже, не существует / или недоступен.
Мое мнение:
@login_required
@permission_required('products.report_upload', raise_exception=True)
def uploadPackingNotesView(request):
    if request.method == "POST":
        form = UploadPackingNotesForm(request.POST, request.FILES)
        if form.is_valid():
            csv_file = form.cleaned_data['csv_upload']
            packing_list = csv.DictReader(io.StringIO(csv_file.read().decode('utf-8')))
            packing_list = list(packing_list)
            print(packing_list) #prints empty list??
            # Pass to Celery for processing
            parsePackingNotes.delay(packing_list)
            return HttpResponseRedirect(reverse_lazy('product-csv-upload-successful'))
    else:
        form = UploadPackingNotesForm()
        return render(request, 'products/upload-packing-notes.html', {'form': UploadPackingNotesForm})
Моя форма:
class UploadPackingNotesForm(forms.Form):
    """Form used to upload packing notes"""
    csv_upload = forms.FileField(label="Select Packing Notes File")
    def clean_csv_upload(self):
        
        data = self.cleaned_data['csv_upload']
        expected_headers = [
            'Branch',
            'Carton',
            'Delivered',
            'SKU',
            'PLU',
            'Supplier Bar Code',
            'Description',
            'Size',
            'Product Type',
        ]
        packing_list = csv.DictReader(io.StringIO(data.read().decode('utf-8')))
        # Check that all required headers are present in the CSV, otherwise return error to frontend
        if not set(expected_headers).issubset(packing_list.fieldnames):
            raise ValidationError("Couldn't read uploaded CSV")
        return data
Я подозреваю, что проблема кроется в строке: csv_file = form.clean_data['csv_upload'] после form.is_valid(), но я не уверен, что нужно использовать, чтобы вернуть подтвержденный файл.
Проблема была в том, что я не понял, что метод .read() не сбрасывает указатель файла (после его использования в функции проверки), поэтому его нужно было сбросить обратно в 0 перед DictReader.
Я изменил блок form.is_valid() на:
if form.is_valid():
    uploaded_csv = form.cleaned_data['csv_upload']
    uploaded_csv.file.seek(0)
    upload_report = list(csv.DictReader(io.StringIO(request.FILES['csv_upload'].read().decode('utf-8'))))
    parseEODReport.delay(upload_report)
    return HttpResponseRedirect(reverse_lazy('product-csv-upload-successful'))
Строка uploaded_csv.file.seek(0) сбрасывает указатель обратно в начало.
Этот пост помог мне в этом.