ホームページ > バックエンド開発 > Python チュートリアル > CSV ファイルを DJANGO REST にアップロードする方法

CSV ファイルを DJANGO REST にアップロードする方法

DDD
リリース: 2024-11-05 19:25:02
オリジナル
810 人が閲覧しました

CSV ファイルを Django REST にアップロードする (特にアトミック設定の場合) のは簡単な作業ですが、これから共有するいくつかのトリックを見つけるまでは戸惑い続けました。
この記事では、(フロントエンドの代わりに) postman を使用し、写真経由でリクエストを送信するために postman で設定する必要がある内容も共有します。

私たちが望むもの

  1. Django Rest 経由で CSV を DB にアップロード
  2. 操作をアトミックにします。つまり、CSV の行にエラーがあると、操作全体が完全にロールバックされます。そのため、CSV ファイルを切り取るストレス、つまり、切り取られた行の部分を特定するという頭痛の種を避けることができます。 DBと途中エラーでできなかったDB! (部分エントリー)。したがって、私たちは全か無かの物事を望んでいます !!

メソッド

  1. Django と Django REST がすでにインストールされていると仮定すると、最初のステップは、データ操作用の Python ライブラリである pandas をインストールすることです。

pip install pandas

  1. postman の次の手順: body タブで、form-data を選択し、キー (任意の名前) を追加します。同じセルで、セルの右端にマウスを置き、ドロップダウンを使用してオプションをテキストからファイルに変更します。これを実行すると、Postman は自動的にヘッダーの Content-Type を multipart/form-data に設定します。

値のセルで、[ファイルを選択] ボタンをクリックし、CSV をアップロードします。以下のスクリーンショットを確認してください

HOW TO UPLOAD A CSV FILE TO DJANGO REST

ヘッダーの下で、Content-Disposition と値を form-data に設定します。名前 = "ファイル";ファイル名 = "あなたのファイル名.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 を使用した理由を説明しています。 Skiprows を削除するか、より小さい数値を使用すると、次のようなエラーが発生する可能性があります: データのトークン化エラー。 C エラーが発生した場合、データがヘッダーから始まっていることに気づくかもしれません。

dtype=str
Panda は、特定の列のデータ型を推測することで賢明であることを証明することを好みます。すべての値を文字列として使用したかったので、 dtype=str

を使用しました。

区切り文字
セルの分割方法を指定します。通常、デフォルトはカンマです。

iloc[:-1]
iloc を使用してデータフレームをスライスし、df の最後にあるメタデータを削除する必要がありました。

次に、次の行 df = df.where(pd.notnull(df), None) は、すべての NaNvalue を None に変換します。 NaN は、パンダが None を表すために使用する代用の値です。

次のブロックは少し難しいです。データフレーム内のすべての行をループし、BiodataModel で行データをインスタンス化し、一括作成では Django 検証をバイパスするため、full_clean() メソッドで (シリアライザー レベルではなく) モデル レベルの検証を実行し、作成操作を というリストに追加します。バルクデータ。はい、追加はまだ実行されていません!アトミックな操作 (バッチ レベルで) を実行しようとしているので、all または None が必要であることを思い出してください。行を個別に保存しても、all or none の動作は行われません。

それでは最後の重要な部分です。 transaction.atomic() ブロック (全か無かの動作を提供します) 内で、BiodataModel.objects.bulk_create(bulk_data) を実行して、すべての行を一度に保存します。

もう一つ。 for ループ内のインデックス変数と例外ブロックに注目してください。 Excel ファイルで見たときに、その値がその値が存在する行と正確に一致しなかったため、Exception ブロックのエラー メッセージで df.iterrows() から派生したインデックス変数に 2 を追加しました。 excel ブロッ​​クはあらゆるエラーをキャッチし、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)

ログイン後にコピー
ログイン後にコピー

以上がCSV ファイルを DJANGO REST にアップロードする方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート