>  기사  >  백엔드 개발  >  DJANGO REST에 CSV 파일을 업로드하는 방법

DJANGO REST에 CSV 파일을 업로드하는 방법

DDD
DDD원래의
2024-11-05 19:25:02781검색

Django REST에 CSV 파일을 업로드하는 것은(특히 원자 설정에서) 간단한 작업이지만 공유할 몇 가지 요령을 발견할 때까지 계속 혼란스러웠습니다.
이 글에서는 (프런트엔드 대신) postman을 사용할 것이며, 사진을 통한 요청 전송을 위해 postman에 설정해야 할 사항도 공유하겠습니다.

우리가 원하는 것

  1. Django Rest를 통해 CSV를 DB에 업로드
  2. 작업을 원자적으로 만듭니다. 즉, csv의 임의 행에 오류가 있으면 전체 작업이 완전히 롤백됩니다. 따라서 csv 파일을 자르는 스트레스, 즉 해당 행의 일부를 식별해야 하는 골치 아픈 일을 피할 수 있습니다. DB와 중간에 오류가 발생하지 않은 것!! (부분 입력). 그래서 우리는 전부 아니면 전무를 원합니다 !!

방법

  1. 이미 Django와 Django REST가 설치되어 있다고 가정하면, 첫 번째 단계는 데이터 조작을 위한 Python 라이브러리인 pandas를 설치하는 것입니다.

pip 설치 팬더

  1. Postman의 다음: 본문 탭에서 양식 데이터를 선택하고 키(임의의 이름)를 추가합니다. 동일한 셀에서 셀의 가장 오른쪽에 마우스를 놓고 드롭다운을 사용하여 옵션을 텍스트에서 파일로 변경합니다. Postman은 이 작업을 수행하는 순간 자동으로 헤더의 Content-Type을 multipart/form-data로 설정합니다.

값 셀의 경우 '파일 선택' 버튼을 클릭하고 CSV를 업로드하세요. 아래 스크린샷을 확인하세요

HOW TO UPLOAD A CSV FILE TO DJANGO REST

헤더 아래에서 Content-Disposition과 값을 form-data로 설정합니다. 이름="파일"; 파일 이름="your_file_name.csv". your_file_name.csv를 실제 파일 이름으로 바꾸십시오. 아래 스크린샷을 확인해보세요.

HOW TO UPLOAD A CSV FILE TO DJANGO REST

  1. Django 뷰의 코드는 다음과 같습니다.
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)

위 코드 설명:
코드는 필요한 패키지를 가져오고, 클래스 기반 보기를 정의하고, 파서 클래스(FileUploadParser)를 설정하는 것으로 시작됩니다. 클래스에 있는 post 메소드의 첫 번째 부분은 request.FILES에서 파일을 가져오고 해당 파일의 가용성을 확인하려고 시도합니다.
그런 다음 간단한 검증을 통해 확장자를 확인하여 CSV인지 확인합니다.
다음 부분에서는 이를 Pandas 데이터 프레임(스프레드시트와 매우 유사)에 로드합니다.
df = pd.read_csv(csv_file, delimiter=',',skiprows=3,dtype=str).iloc[:-1]
로딩 함수에 전달되는 몇 가지 인수에 대해 설명하겠습니다.

건너뛰기
로드된 csv 파일을 읽을 때 이 경우 csv는 네트워크를 통해 전달되므로 항목과 같은 일부 메타데이터가 파일의 시작과 끝에 추가된다는 점에 유의해야 합니다. 이러한 것들은 성가실 수 있고 쉼표로 구분된 값(csv) 형식이 아니므로 실제로 구문 분석 시 오류가 발생할 수 있습니다. 이는 메타데이터와 헤더가 포함된 처음 3개 행을 건너뛰고 CSV 본문에 직접 배치하기 위해 Skiprows=3을 사용한 이유를 설명합니다. Skiprow를 제거하거나 더 적은 숫자를 사용하는 경우 다음과 같은 오류가 발생할 수 있습니다. 데이터 토큰화 중 오류가 발생했습니다. C 오류가 발생하거나 헤더부터 데이터가 시작되는 것을 볼 수 있습니다.

dtype=str
Pandas는 특정 열의 데이터 유형을 추측하는 데 현명함을 입증하는 것을 좋아합니다. 모든 값을 문자열로 원했기 때문에 dtype=str

을 사용했습니다.

구분자
셀이 분리되는 방법을 지정합니다. 기본값은 일반적으로 쉼표입니다.

iloc[:-1]
iloc를 사용하여 데이터프레임을 분할하고 df 끝의 메타데이터를 제거해야 했습니다.

그런 다음 다음 줄 df = df.where(pd.notnull(df), None)은 모든 NaN 값을 None으로 변환합니다. NaNi는 pandas가 None을 나타내는 데 사용하는 대체 값입니다.

다음 블록이 좀 까다롭네요. 데이터프레임의 모든 행을 반복하고, BiodataModel을 사용하여 행 데이터를 인스턴스화하고, 대량 생성이 Django 검증을 우회하기 때문에 full_clean() 메서드를 사용하여 모델 수준 검증(시리얼라이저 수준 아님)을 수행한 다음 생성 작업을 호출된 목록에 추가합니다. 대량 데이터. 예, 추가는 아직 실행되지 않았습니다! 기억하세요. 우리는 원자적 작업(배치 수준에서)을 수행하려고 하므로 모두 또는 없음을 원합니다. 행을 개별적으로 저장한다고 해서 모든 동작이 제공되거나 전혀 제공되지는 않습니다.

그럼 마지막으로 중요한 부분입니다. transaction.atomic() 블록(동작 전체 또는 없음 제공) 내에서 BiodataModel.objects.bulk_create(bulk_data)를 실행하여 모든 행을 한 번에 저장합니다.

한 가지 더. for 루프의 index 변수와 Except 블록을 확인하세요. 블록 제외 오류 메시지에서 df.iterrows()에서 파생된 index변수에 2를 추가했습니다. Excel 파일에서 볼 때 해당 값이 해당 행과 정확히 일치하지 않았기 때문입니다. Except 블록은 모든 오류를 포착하고 Excel에서 열 때 정확한 행 번호가 포함된 오류 메시지를 구성하므로 업로더가 Excel 파일에서 해당 줄을 쉽게 찾을 수 있습니다!

읽어주셔서 감사합니다!!!

사용된 도구 버전

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)

위 내용은 DJANGO REST에 CSV 파일을 업로드하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.