0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[DRF]結合テーブルの更新(part4)【update】【drf-writable-nested】

Posted at

Django-rest-frameworkでAPIを作成します

前回までの記事一覧です。

基本編
[DRF]apiの作成(patch)
[DRF]apiの作成(post)
[DRF]apiの作成(get)part2
[DRF]apiの作成(get)part1
応用編
[DRF]結合テーブルの更新(part3)
[DRF]結合テーブルの更新(part2)
[DRF]結合テーブルの更新(part1)
[DRF]結合テーブルの取得

前回の記事では、serializerでupdateメソッドをオーバーライドすることにより自前でネストされたテーブルを更新しました。今回はcreateのときと同じく、drf-writable-nestedを使用して、更新の処理を実装していきます。

model

modelは以下のとおりです。

models.py
from django.db import models

DISTRICT_CATEGORIES = [
    ("1", "地区1"),
    ("2", "地区2"),
    ("3", "地区3"),
    ("4", "地区4"),
]


class Student(models.Model):
    """生徒情報"""

    # 生徒ID
    student_id = models.CharField(max_length=4, primary_key=True)

    # クラス
    class_no = models.CharField(max_length=1)

    # 出席番号
    attendance_no = models.IntegerField()

    # 名前
    name = models.CharField(max_length=20)

    # 地区番号
    district_no = models.CharField(max_length=1, choices=DISTRICT_CATEGORIES)

    # フリーコメント
    comment = models.CharField(max_length=200,blank=True)

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=["class_no", "attendance_no"],
                name="class_attendance_unique"
            ),
        ]


class Exam(models.Model):
    """試験情報"""

    # 国語
    japanese_score = models.IntegerField(null=True, blank=True)

    # 数学
    math_score = models.IntegerField(null=True, blank=True)

    # 英語
    english_score = models.IntegerField(null=True, blank=True)

    # 生徒ID
    student = models.OneToOneField(Student, on_delete=models.CASCADE)

StudentとExamが1対1対応しています。

update

今回は既存レコードを更新します。

view

viewは前回と変わっていません。

views.py
from django.shortcuts import get_object_or_404

from rest_framework.views import APIView
from rest_framework.response import Response
from ..models import Student
from ..serializers import StudentExamUpdateSerializer


class StudentExamUpdateAPIView(APIView):
    """生徒情報、試験情報を登録"""

    def post(self, request, pk, *args, **kwargs):

        instance = get_object_or_404(Student, pk=pk)

        # serializer作成
        serializer = StudentExamUpdateSerializer(instance=instance, data=request.data, partial=True)

        # validate
        try:
            serializer.is_valid(raise_exception=True)
        except Exception:
            raise Exception

        serializer.save()

        # Response
        return Response({'result':True})

serializer

WritableNestedModelSerializerを継承しています。
createのときと同じですね。

serializers.py
from rest_framework import serializers
from ..models import Student, Exam
from drf_writable_nested.serializers import WritableNestedModelSerializer


class ExamOfStudentExamUpdateSerializer(serializers.ModelSerializer):
    """Examクラスのシリアライザ"""

    class Meta:
        model = Exam
        fields=[
            'japanese_score',
            'math_score',
            'english_score'
        ]


class StudentExamUpdateSerializer(WritableNestedModelSerializer):
    """Studentクラスのシリアライザ"""

    exam = ExamOfStudentExamUpdateSerializer()

    class Meta:
        model = Student
        fields = [
            'student_id',
            'class_no',
            'attendance_no',
            'name',
            'district_no',
            'comment',
            'exam'
        ]

実行

import requests
import json

student_id='0002'
name="なまえ"

english_score = 55
exam = {
    'english_score': english_score,
}
body = {
    'name': name,
    'exam': exam,
}

headers = {"Content-Type" : "application/json;charset=UTF-8"}
response = requests.post('http://127.0.0.1:8000/student/{}/student_exam_update/'.format(student_id), data=json.dumps(body), headers=headers)

print(response.text)

{"result":true}

実行前

STUDENT ID CLASS NO ATTENDANCE NO NAME DISTRICT NO COMMENT
0002 1 2 山田花子 地区2 1組2番
STUDENT ID JAPANESE SCORE MATH SCORE ENGLISH SCORE
0002 100 100 100

実行後

STUDENT ID CLASS NO ATTENDANCE NO NAME DISTRICT NO COMMENT
0002 1 2 なまえ 地区2 1組2番
STUDENT ID JAPANESE SCORE MATH SCORE ENGLISH SCORE
0002 100 100 55

簡単にできちゃいました。。。
WritableNestedModelSerializer、便利ですね・・・。
githubリポジトリもぜひ参照されたいところです。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?