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リポジトリもぜひ参照されたいところです。