iT邦幫忙

2023 iThome 鐵人賽

DAY 23
0

前言

昨天講了一個比較複雜的操作,今天我們來做一點點輕鬆的,順便當作複習前面的,今天要的是把分類相關的功能實作完成吧。

Serializer

首先是序列化讓我們編輯 server/app/todo/serializers.py 檔案

# ...... 以上省略 ......

class TagSerializer(serializers.ModelSerializer):
    class Meta:
        model = todo_models.Tag
        fields = "__all__"


+class CategorySerializer(serializers.ModelSerializer):
+    class Meta:
+        model = todo_models.Category
+        fields = "__all__"


class TaskSerializer(serializers.ModelSerializer):

# ...... 以下省略 ......

這邊是建立了一個 CategorySerializer 序列化,接受所有 Category 的欄位傳入跟傳出。

ViewSet

接下來是 ViewSet 讓我們編輯 server/app/todo/views.py 檔案(將下面那段貼在檔案最下面)

class CategoryViewSet(viewsets.ModelViewSet):
    queryset = todo_models.Category.objects.order_by("id")
    serializer_class = todo_serializers.CategorySerializer
    ordering_fields = ("id", "name")
    search_fields = ("name",)
    filterset_fields = {
        "name": ("exact", "contains", "icontains"),
    }

這邊是建立了一個 CategoryViewSet 資料的範圍是全部的分類(依 ID 排序)並使用 CategorySerializer 作為格式同時設定排序、搜尋與篩選的功能。

URL

接下來是路由相關的設定讓我們編輯 server/urls.py 檔案

# ...... 以上省略 ......

router = routers.SimpleRouter(trailing_slash=False)
router.register("todo/tasks", todo_views.TaskViewSet)
router.register("todo/tags", todo_views.TagViewSet)
+router.register("todo/categories", todo_views.CategoryViewSet)

urlpatterns = [

# ...... 以下省略 ......

現在我們已將 CategoryViewSet 註冊進去了,現在大家可以試試看現在分類相關的增刪改查的功能都已經完成了~大家可以利用 Postman 試試看

P.S. 大家可能會發現這邊我路由用的是 categories 而不是 category 是因為 RESTful 的路由習慣用複數當作路徑名稱,所以這邊的 url 會是 http://127.0.0.1:8000/api/todo/categories

Admin

接下來是 Admin 部分讓我們編輯 server/app/todo/admin.py 檔案

from django.contrib import admin

from server.app.todo import models as todo_models


@admin.register(todo_models.Task)
class TaskAdmin(admin.ModelAdmin):
    list_display = ("title", "is_finish")
-   list_filter = ("is_finish", "tags")
+   list_filter = ("is_finish", "tags", "category")
    search_fields = ("title", "description")
    filter_horizontal = ("tags",)


@admin.register(todo_models.Tag)
class TagAdmin(admin.ModelAdmin):
    pass

+
+@admin.register(todo_models.Category)
+class CategoryAdmin(admin.ModelAdmin):
+    pass

我們在這邊新增 CategoryAdmin 讓 Category 可以在 Admin 系統編輯相關資料

調整 TaskSerializer

跟之前的 Tag 的時候一樣我們需要讓我們呼叫 Task 列表 API 的時候可以拿到分類的的名稱,這樣就不用呼叫多次 API 來得到對的資料了

# ...... 以上省略 ......

class TaskSerializer(serializers.ModelSerializer):
    tags = TagSerializer(many=True, read_only=True)
    tag_ids = serializers.PrimaryKeyRelatedField(
        allow_empty=False,
        write_only=True,
        many=True,
        queryset=todo_models.Tag.objects.all(),
        source="tags",
    )

+   category = CategorySerializer(read_only=True)
+   category_id = serializers.PrimaryKeyRelatedField(
+       write_only=True,
+       queryset=todo_models.Category.objects.all(),
+       source="category",
+   )
+
    class Meta:
        model = todo_models.Task
        fields = "__all__"

# ...... 以下省略

現在這樣我們建立 Task 時就可以利用 category_id 指定關聯的分類,並從 category 欄位得到分類的完整資訊(包含 ID 與 name)

總結

今天做的東西都比較簡單,算是複習前面的內容,但還是需要做,因為後面的範例會使用到~

結束前別忘了檢查一下今天的程式碼有沒有問題,並排版好喔。

ruff check --fix .
black .
pyright .

今天的內容就到這邊了,讓我們期待明天的內容吧。

P.S. 今天的檔案更新可以參考我的 Git Commit 大家可以搭配服用


上一篇
Day22 - 客製化遷移檔(migration)
下一篇
Day24 - 使用 django-extensions 協助開發
系列文
Django REST 大冒險:探索精彩紛呈的 API 開發世界30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言