Django CSV上传到数据库,但引发错误

发布于 2025-02-13 19:47:17 字数 4397 浏览 0 评论 0原文

我在使用Django的一个名为网站的项目中创建了一个名为客户的应用程序。我已经在连接到Postgres DB的管理区域中创建了CSV上传。

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 %}


Traceback error:
Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/admin/search/customer/upload-csv/

Django Version: 4.0.5
Python Version: 3.9.2
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'search',
 'django.contrib.postgres',
 'import_export']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "C:\Users\acart\Desktop\New folder\venv\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
    response = get_response(request)
  File "C:\Users\acart\Desktop\New folder\venv\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\acart\Desktop\New folder\website\search\admin.py", line 51, in upload_csv
    balance=fields[1],

Exception Type: IndexError at /admin/search/customer/upload-csv/
Exception Value: list index out of range

I have created an app named customer within a project named Website using django. I have created a csv upload in the admin area which is connected to the Postgres db.

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

However the CSV file is still added to the db but the error screen is displayed.
Even more strangely if I a notepad doc as csv containing the data and upload that I get no error until I try to upload a second data set. If I save an excel doc as csv I get the error. Where am I going wrong ?

 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 %}


Traceback error:
Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/admin/search/customer/upload-csv/

Django Version: 4.0.5
Python Version: 3.9.2
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'search',
 'django.contrib.postgres',
 'import_export']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "C:\Users\acart\Desktop\New folder\venv\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
    response = get_response(request)
  File "C:\Users\acart\Desktop\New folder\venv\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\acart\Desktop\New folder\website\search\admin.py", line 51, in upload_csv
    balance=fields[1],

Exception Type: IndexError at /admin/search/customer/upload-csv/
Exception Value: list index out of range

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

热鲨 2025-02-20 19:47:17

由于CSV的性质,您需要检查是否长度
字段项目为2。

即,以

            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。

Due to the nature of csv, you need to check if the length of your
field item is 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],
                    )

This way, you skip processing lines which are empty. Note that I'm assuming your expected field lengths is 2.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文