Djangoでモデルの更新と削除のAPIを実装する
最近ブログ書くの楽しい😉
いつまで続くかな?
前回の続きです。
前回がlist
とcreate
だったので、今回はupdate
とdelete
です👍
何がしたいの?
公式のチュートリアルをベースにupdate
とデレて
を実装します
前提
今回は前回のリポジトリ(これ↓)の上に実装していきます!👍
https://github.com/sisi100/django-my-template/tree/post/hello_model
⚠ 動かしやすさのため記事ではパラメーターのやり取りにGET
を使ってますが、実サービスの場合はセキュリティに問題あるのでPOST
とかPUT
とかDELETE
とかとか使ってください🙇
では 作っていきましょう👻
まずview
の追加とエンドポイントを作るので、このあたりは前々回やっているのでダイジェストで行きます。
はじめにviews.py
の末尾に下記のような2つの関数を追加します。
# ... 略
def user_update(request: WSGIRequest, user_id: int) -> JsonResponse:
""" ユーザー情報を更新する """
return JsonResponse({})
def user_delete(request: WSGIRequest, user_id: int) -> JsonResponse:
""" ユーザーを削除する """
return JsonResponse({})
エンドポイントを登録します。
urls.py
に登録した関数とエンドポイントを紐付けます。
from django.urls import path
from .views import user_list, user_create, user_update, user_delete
urlpatterns = [
path("users/", user_list),
path("users/<int:user_id>/create/", user_create),
path("users/<int:user_id>/update/", user_update),
path("users/<int:user_id>/delete/", user_delete),
]
サーバーを起動してブラウザでhttp://localhost:8000/hello/
を叩くと、今はこんな感じ
updateで変更する情報がないので、モデルに変数を追加します。
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
class User(models.Model):
name = models.CharField(verbose_name="名前", max_length=200)
age = models.PositiveSmallIntegerField(
verbose_name="年齢",
validators=[MinValueValidator(0), MaxValueValidator(200)],
)
年齢が追加しました。あと変数の和名を追加してみました。
age
の後ろにあるvalidators以降
はバリデーションで0〜200
以外入れませんよ!という意味です。
次にこの設定をDBに登録するためmigrationします。
$ python manage.py makemigrations
$ python manage.py migrate
# django-my-templateを使用の方は↓
$ make makemigrations
$ make migrate
このときこんな(↓)ことをメッセージがでた場合は、age
追加したけど、既存DBのユーザーのage
どうすんの?と聞いてきているので、初期値デフォルトをいれるかDBを一回削除してください笑
You are trying to add a non-nullable field 'age' to user without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
2) Quit, and let me add a default in models.py
Select an option:
# ここではデフォルト入れる方法を紹介
> 1
Please enter the default value now, as valid Python
> 20
# デフォルト20歳
# 後はmigrateを叩いてください👍
これでユーザーモデルは名前
と年齢
を持つようになりました😉
views.py
のcreate
とlist
がage
に対応してないので修正します。
# ... 略
def user_list(request: WSGIRequest) -> JsonResponse:
""" ユーザー一覧を表示する """
users = User.objects.all()
user_list = [
{"id": user.id, "name": user.name, "age": user.age} for user in users
]
return JsonResponse({"user_list": user_list})
def user_create(request: WSGIRequest, user_id: int) -> JsonResponse:
""" 新規にユーザーを作る """
name = request.GET.get("name") or "No Name"
age = request.GET.get("age") or "20"
user = User(id=user_id, name=name)
user.save()
return JsonResponse({"id": user.id, "name": user.name, "age": user.age})
# ... 略
スクショの動作確認省きますが、下記を叩くとid=1
に次郎くん3歳
が登録されるはずです
http://localhost:8000/hello/users/1/create/?name=ziro-&age=3
さて本題はここからですね😅
user_updateを実装する
# ... 略
def user_update(request: WSGIRequest, user_id: int) -> JsonResponse:
""" ユーザー情報を更新する """
user = User.objects.get(id=user_id)
if name := request.GET.get("name"):
user.name = name
if age := request.GET.get("age"):
user.age = age
user.full_clean()
user.save()
return JsonResponse({})
# ... 略
うん、すごく冗長(笑)
もっと短く書く方法はありますが、分かりにくい気がするので一旦こんな書き方です🤔
ちなみに、登録されていないuser_id
を指定するとモレなく落ちます(DoesNotExist
)ので覚悟してください😉
先に登録した次郎くん
が30歳
になったと想定して下記を叩きます
http://localhost:8000/hello/users/1/update/?age=30
その後user_list
で次郎くん
の様子を見てみましょう
http://localhost:8000/hello/users/
ちょっと前回作った邪魔なユーザーいますが、無事次郎くん
は30歳
になりました。
ちなみに次郎くん
を300歳
に設定しようとすると怒られます。
http://localhost:8000/hello/users/1/update/?age=300
user_deleteを実装する
# ... 略
def user_delete(request: WSGIRequest, user_id: int) -> JsonResponse:
""" ユーザーを削除する """
user = User.objects.get(id=user_id)
user.delete()
return JsonResponse({})
# ... 略
はい、短い。
次郎くん
以外のユーザーを削除してみます。
http://localhost:8000/hello/users/2/delete/
http://localhost:8000/hello/users/3/delete/
http://localhost:8000/hello/users/4/delete/
user_listを確認します。
http://localhost:8000/hello/users/
はい、無事次郎くん
以外を削除することができました👍
まとめ
前回に引き続きDjangoでupdate
とdelete
のAPIを作りました! 以上(笑
ありがとうございましたー!😉
今回のリポジトリはこちら
https://github.com/sisi100/django-my-template/tree/post/hello_model_2