Django загрузка csv в базу данных работает, но выдает ошибку

Я создал приложение под названием Customer в проекте под названием Website, используя django. Я создал выгрузку csv в области администратора, которая подключена к базе данных Postgres.

An error occurs when I upload the CSV returning:
Exception Type:     IndexError
Exception Value:    list index out of range

Однако CSV-файл по-прежнему добавляется в базу данных, но отображается экран ошибки. Еще более странно, что если я сохраняю в блокноте документ в формате csv, содержащий данные, и загружаю его, то не получаю никакой ошибки, пока не попытаюсь загрузить второй набор данных. Если я сохраняю документ excel в формате csv, я получаю ошибку. Где я ошибаюсь?

 Models.py
    class customer(models.Model):
        name = models.CharField(max_length=50, blank=True)
        balance = models.CharField(max_length=120, blank=True)    
    
        def __str__(self):
            return self.name

Admin.py
from django.contrib import admin
from django.urls import path
from django.shortcuts import render, redirect
from .models import customer
from django import forms
from django.contrib import messages
from django.http import HttpResponseRedirect
from django.urls import reverse
from import_export import resources


class data(resources.ModelResource):

    class Meta:
        model = customer


class CsvImportForm(forms.Form):
    csv_upload = forms.FileField()


class CustomerAdmin(admin.ModelAdmin):
    list_display = ('name', 'balance',)

    def get_urls(self):
        urls = super().get_urls()
        new_urls = [path('upload-csv/', self.upload_csv), ]
        return new_urls + urls



   
   
    def upload_csv(self, request):       

        if request.method == "POST":
            print("action is POST")
            csv_file = request.FILES["csv_upload"]

            if not csv_file.name.endswith('.csv'):
                messages.warning(request, 'The wrong file type was uploaded')
                return HttpResponseRedirect(request.path_info)

            file_data = csv_file.read().decode("utf-8")
            csv_data = file_data.split("\n")

            for x in csv_data:
                fields = x.split(",")
                created = customer.objects.update_or_create(
                    name=fields[0],
                    balance=fields[1],
                )
        
        

        form = CsvImportForm()
        data = {"form": form}
        return render(request, "admin/search/csv_upload.html", data)
         

        

admin.site.register(customer, CustomerAdmin)



csv_upload.html
{% extends 'admin/index.html' %}

{% block content %}
    <div>
        <form action ="." method="POST" enctype="multipart/form-data">
            {{ form.as_p }}
            {% csrf_token %}
            <h1>Hello World upload files here to db</h1>
            <button type="submit">Upload file</button>
        </form>
    </div>
{% endblock %}


change_list.html
{% extends 'admin/change_list.html' %}

{% load static %}

{% block content %}

    <br><br>
    <a href="upload-csv/">Upload a csv file</a>
    <br><br><br>

    <!-- Gives us all the other elements ont he page we want to access. -->
    {{ block.super }}

{% endblock %}

В связи с природой csv, вам необходимо проверить, является ли длина вашего field элемента равна 2.

i.e.

            for x in csv_data:
                fields = x.split(",")
                if len(fields) == 2:
                    created = customer.objects.update_or_create(
                        name=fields[0],
                        balance=fields[1],
                    )

Таким образом, вы пропускаете обработку пустых строк. Обратите внимание, что я предполагаю, что ожидаемая длина полей равна 2.

Вернуться на верх