/ #Django 

Djangoでモデルの更新と削除のAPIを実装する

もくじ

最近ブログ書くの楽しい😉
いつまで続くかな?

前回の続きです。

前回がlistcreateだったので、今回はupdatedeleteです👍

何がしたいの?

公式のチュートリアルをベースに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.pycreatelistageに対応してないので修正します。


# ... 略

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でupdatedeleteのAPIを作りました! 以上(笑

ありがとうございましたー!😉

今回のリポジトリはこちら

https://github.com/sisi100/django-my-template/tree/post/hello_model_2

Author

Sisii

インフラが好きなエンジニアぶってるなにか