BAGAIMANA UNTUK MUAT NAIK FAIL CSV KE DJANGO REST

DDD
Lepaskan: 2024-11-05 19:25:02
asal
729 orang telah melayarinya

Memuat naik fail CSV ke Django REST (terutamanya dalam tetapan atom) adalah tugas yang mudah, tetapi membuatkan saya tertanya-tanya sehingga saya mengetahui beberapa helah yang akan saya kongsikan dengan anda.
Dalam artikel ini, saya akan menggunakan posmen (menggantikan bahagian hadapan) dan juga akan berkongsi perkara yang anda perlu tetapkan pada posmen untuk menghantar permintaan melalui gambar.

Apa yang kita inginkan

  1. Muat naik CSV melalui Django Rest ke DB
  2. Jadikan operasi atom iaitu sebarang ralat dalam mana-mana baris daripada csv akan menyebabkan pemulangan sepenuhnya keseluruhan operasi, jadi kita boleh mengelakkan tekanan memotong fail csv iaitu sakit kepala untuk mengenal pasti bahagian baris yang membuatnya menjadi DB dan yang tidak berlaku kerana sebarang ralat di tengah jalan!! (kemasukan separa). Jadi kami mahukan semua-atau-tiada perkara !!

Kaedah

  1. Dengan andaian, anda sudah memasang Django dan Django REST, langkah pertama ialah memasang panda, perpustakaan ular sawa untuk manipulasi data.

pip pasang panda

  1. Seterusnya dalam posmen: Dalam tab badan, pilih borang-data dan tambahkan kunci (sebarang nama sewenang-wenangnya). Dalam sel yang sama, tuding pada bahagian paling kanan sel dan gunakan menu lungsur untuk menukar pilihan daripada teks ke fail. Posmen akan secara automatik menetapkan Jenis Kandungan kepada berbilang bahagian/data-bentuk dalam Pengepala sebaik sahaja anda melakukan ini.

Untuk sel nilai, klik butang 'Pilih Fail' dan muat naik CSV. Semak tangkapan skrin di bawah

HOW TO UPLOAD A CSV FILE TO DJANGO REST

Di bawah pengepala, tetapkan Pelupusan Kandungan dan nilai kepada data bentuk; nama = "fail"; nama fail="nama_fail_anda.csv". Gantikan nama_fail anda.csv dengan nama fail sebenar anda. Semak tangkapan skrin di bawah.

HOW TO UPLOAD A CSV FILE TO DJANGO REST

  1. Dalam paparan Django, kodnya adalah seperti berikut:
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.parsers import FileUploadParser
from rest_framework.response import Response
from .models import BiodataModel
from django.db import transaction
import pandas as pd

class UploadCSVFile(APIView):
    parser_classes = [FileUploadParser]

    def post(self,request): 
        csv_file = request.FILES.get('file')
        if not csv_file:
            return Response({"error": "No file provided"}, status=status.HTTP_400_BAD_REQUEST)

        # Validate file type
        if not csv_file.name.endswith('.csv'):
            return Response({"error": "File is not CSV type"}, status=status.HTTP_400_BAD_REQUEST)

        df = pd.read_csv(csv_file, delimiter=',',skiprows=3,dtype=str).iloc[:-1]
        df = df.where(pd.notnull(df), None)

        bulk_data=[]
        for index, row in df.iterrows():
            try:
              row_instance= BiodataModel(
                      name=row.get('name'),
                      age=row.get('age'),
                      address =row.get('address'))
              row_instance.full_clean()
              bulk_data.append(row_instance)
            except Exception as e:
                return Response({"error": f'Error at row {index + 2} -> {e}'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            with transaction.atomic():
                BiodataModel.objects.bulk_create(bulk_data)
        except Exception as e:
            return Response({"error": f'Bulk create error--{e}'}, status=status.HTTP_400_BAD_REQUEST)
        return Response({"msg":"CSV file processed successfully"}, status=status.HTTP_201_CREATED)

Salin selepas log masuk
Salin selepas log masuk

Menjelaskan kod di atas:
Kod ini bermula dengan mengimport pakej yang diperlukan, mentakrifkan pandangan berasaskan kelas dan menetapkan kelas parser (FileUploadParser). Bahagian pertama kaedah siaran dalam kelas cuba mendapatkan fail daripada request.FILES dan semak ketersediaannya.
Kemudian pengesahan kecil menyemak bahawa ia adalah CSV dengan menyemak sambungan.
Bahagian seterusnya memuatkannya ke dalam bingkai data panda (sangat mirip hamparan):
df = pd.read_csv(csv_file, delimiter=',',skiprows=3,dtype=str).iloc[:-1]
Saya akan menerangkan beberapa hujah yang dihantar kepada fungsi pemuatan:

kayuh ski
Dalam membaca fail csv yang dimuatkan, perlu diperhatikan bahawa csv dalam kes ini diluluskan melalui rangkaian, jadi beberapa metadata seperti bahan ditambahkan pada permulaan dan penghujung fail. Perkara ini boleh menjengkelkan dan bukan dalam bentuk nilai dipisahkan koma (csv) jadi sebenarnya boleh menimbulkan ralat dalam penghuraian. Ini menerangkan sebab saya menggunakan skiprows=3, untuk melangkau 3 baris pertama yang mengandungi metadata dan pengepala dan mendarat terus pada badan csv. Jika anda mengalih keluar skiprowatau menggunakan nombor yang lebih kecil, mungkin anda mungkin mendapat ralat seperti: Ralat token data. Ralat C atau anda mungkin melihat data bermula dari pengepala.

dtype=str
Panda suka membuktikan pintar dalam cuba meneka jenis data lajur tertentu. Saya mahukan semua nilai sebagai rentetan, jadi saya menggunakan dtype=str

pembatas
Menentukan cara sel dipisahkan. Lalai biasanya koma.

iloc[:-1]
Saya terpaksa menggunakan iloc untuk menghiris bingkai data, mengalih keluar metadata pada penghujung df.

Kemudian, baris seterusnya df = df.where(pd.notnull(df), None) menukar semua NaNvalues ​​kepada None. NaNi ialah nilai tetap yang digunakan oleh panda untuk mewakili Tiada.

Blok seterusnya agak rumit. Kami menggelungkan setiap baris dalam bingkai data, membuat instantiate data baris dengan BiodataModel, melaksanakan pengesahan peringkat model (bukan peringkat serializer) dengan kaedah full_clean() kerana ciptaan pukal memintas pengesahan Django, dan kemudian menambah operasi ciptaan kami pada senarai yang dipanggil bulk_data. Ya , tambah belum jalan ! Ingat, kami cuba melakukan operasi atom (pada peringkat kelompok ) jadi kami mahu semua atau Tiada. Menyimpan baris secara individu tidak akan memberi kita semua atau tiada gelagat.

Kemudian untuk bahagian penting yang terakhir. Dalam blok transaction.atomic() (yang menyediakan semua atau tiada gelagat), kami menjalankan BiodataModel.objects.bulk_create(bulk_data) untuk menyimpan semua baris sekaligus.

Satu perkara lagi. Perhatikan pembolehubah indeks dan blok kecuali dalam gelung for. Dalam mesej ralat blok kecuali, saya menambah 2 pada pembolehubah indeks yang diperoleh daripada df.iterrows() kerana nilai itu tidak sepadan dengan baris yang dihidupkan, apabila dilihat dalam fail excel. Blok except menangkap sebarang ralat dan membina mesej ralat yang mempunyai nombor baris yang tepat apabila dibuka dalam excel, supaya pemuat naik dapat mengesan baris dalam fail excel dengan mudah!

Terima kasih kerana membaca!!!

VERSI ALAT YANG DIGUNAKAN

from rest_framework import status
from rest_framework.views import APIView
from rest_framework.parsers import FileUploadParser
from rest_framework.response import Response
from .models import BiodataModel
from django.db import transaction
import pandas as pd

class UploadCSVFile(APIView):
    parser_classes = [FileUploadParser]

    def post(self,request): 
        csv_file = request.FILES.get('file')
        if not csv_file:
            return Response({"error": "No file provided"}, status=status.HTTP_400_BAD_REQUEST)

        # Validate file type
        if not csv_file.name.endswith('.csv'):
            return Response({"error": "File is not CSV type"}, status=status.HTTP_400_BAD_REQUEST)

        df = pd.read_csv(csv_file, delimiter=',',skiprows=3,dtype=str).iloc[:-1]
        df = df.where(pd.notnull(df), None)

        bulk_data=[]
        for index, row in df.iterrows():
            try:
              row_instance= BiodataModel(
                      name=row.get('name'),
                      age=row.get('age'),
                      address =row.get('address'))
              row_instance.full_clean()
              bulk_data.append(row_instance)
            except Exception as e:
                return Response({"error": f'Error at row {index + 2} -> {e}'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            with transaction.atomic():
                BiodataModel.objects.bulk_create(bulk_data)
        except Exception as e:
            return Response({"error": f'Bulk create error--{e}'}, status=status.HTTP_400_BAD_REQUEST)
        return Response({"msg":"CSV file processed successfully"}, status=status.HTTP_201_CREATED)

Salin selepas log masuk
Salin selepas log masuk

Atas ialah kandungan terperinci BAGAIMANA UNTUK MUAT NAIK FAIL CSV KE DJANGO REST. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!