概要
今回はPOSTする際にrequestの中のCSVファイルのデータをデータベースにINSERTする方法について記載していきます
はじめに
以下のファイルに必要な設定を記載していきます
- models.py
- serializers.py
- views.py
models.py
お客様用のModelを作成します
models.py
import uuid
from django.db import models
from django.core.validators import RegexValidator
class Customer(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=255)
kana = models.CharField(max_length=255)
birthday = models.DateField()
post_no = models.CharField(
max_length=7, validators=[RegexValidator(r"^[0-9]{7}$", "7桁の数字を入力してください。")]
)
phone_no = models.CharField(
max_length=11,
validators=[RegexValidator(r"^[0-9]{10,11}$", "10桁の数字を入力してください。")],
null=True,
blank=True,
)
email = models.EmailField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
created_by = models.ForeignKey(User, on_delete=models.DO_NOTHING, related_name='%(class)s_created_by')
updated_at = models.DateTimeField(auto_now=True)
updated_by = models.ForeignKey(User, on_delete=models.DO_NOTHING, related_name='%(class)s_updated_by')
class Meta:
db_table = "Customer"
def __str__(self):
return self.name
serializers.py
ファイルのアップロードをするときはSerializerのFileFieldを使用します
そうすることでPOSTする際のrequest内にCSVファイルを入れることができます
今回はfileという名前のfieldにします
その際はserializers.Serializerクラスを継承させます
serializers.py
# ファイルアップロード用Serializer
class CreateCustomerSerializer(serializers.Serializer):
file = serializers.FileField()
# お客様用Serializer
class CustomerSerializer(serializers.ModelSerializer):
class Meta:
model = Customer
fields = "__all__"
read_only_fields = ["id","created_at","created_by","updated_at","updated_by"]
views.py
views.pyにCSVファイル内のデータをPOSTする処理を記載していきます
views.py
import csv, io, datetime
from rest_framework import viewsets
from django.http import JsonResponse
from rest_framework import status
from .models import Customer
from .serializers import (
CustomerSerializer,
CreateCustomerSerializer,
)
class CustomerViewSet(viewsets.ModelViewSet):
queryset = Customer.objects.all()
# POSTの時だけ
def get_serializer_class(self):
if self.action == "create":
return CreateCustomerSerializer
else:
return CustomerSerializer
def create(self, request, *args, **kwargs):
# request.FILESからSerializerで定義したfileを指定
# CSVファイルがInMemoryUploadedFile型として格納されている
csv_file = request.FILES["file"]
# utf-8に変換
decoded_file = csv_file.read().decode("utf-8")
io_string = io.StringIO(decoded_file)
# header(1行目)を無視
header = next(csv.reader(io_string))
# delimiter=","と指定し、CSVファイルを1行ずつ読み込む
for row in csv.reader(io_string, delimiter=","):
# CSVファイルの内容はstr型のため、birthdayをdate型にキャストする必要がある
year = int(row[2].split("/")[0])
month = int(row[2].split("/")[1])
day = int(row[2].split("/")[2])
birthday = datetime.date(year, month, day)
# Customerに必要なデータ
csv_data = {
"name": row[0],
"kana": row[1],
"birthday": birthday,
"post_no": row[3],
"phone_no": "0" + row[4],
"email": row[5],
}
serializer = CustomerSerializer(data=csv_data)
if serializer.is_valid():
serializer.save(created_by=request.user,updated_by=request.user)
else:
return JsonResponse({"msg":"CSVファイルのアップロードに失敗しました"},status=status.HTTP_400_CREATED)
return JsonResponse({"msg":"CSVファイルのアップロードに成功しました"},status=status.HTTP_201_CREATED)
実際にCSVをPOSTしてみよう!
該当するエンドポイントにアクセスすると下記のようにファイルを添付することができます
参考