iT邦幫忙

2023 iThome 鐵人賽

DAY 26
0
自我挑戰組

轉職新手學 Django 及 DRF系列 第 26

Day 26 - 製作 API (五) Book model 相關

  • 分享至 

  • xImage
  •  

今天來製作 books API 端點!

book app & book model

首先要先創建一個新的 app,到rest_api中輸入:

python manage.py startapp book

建立完成後記得加入settings.pyINSTALLED_APPS中。books app 預計只會有 serializers, urls, views,而 book model 會加在 core app 中。再來到core/models.py中加入:

# 其他導入
from django.conf import settings

# ...
class Book(models.Model):
    """Book object."""
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
    )
    title = models.CharField(max_length=255)
    description = models.TextField(blank=True)
    price = models.IntegerField()

    def __str__(self):
        return self.title

這邊在 book model 底下創建四個欄位: user, title, description, price。ForeignKey可使兩欄位產生連結,第一個參數為了避免 hard code,所以使用settings.AUTH_USER_MODEL,而on_delete=models.CASCADE表示 user 被刪除時,其創建的 book object 也會一併被刪除。最底下的__str__函式會將 title 顯示在管理員頁面中。完成後儲存並執行 migration 創建此資料表。最後記得在admin.py中註冊此 model。

此處 Book 繼承的是models.Model,與 User model 不同。

book serializers & book views

接著到 book app 中新增serializers.py檔案並加入:

from rest_framework import serializers
from core.models import Book

class BookSerializer(serializers.ModelSerializer):
    """Serializer for books."""

    class Meta:
        model = Book
        fields = ['id', 'title', 'price']
        read_only_fields = ['id']

這邊的 serializer 同樣繼承ModelSerializer並指定 Book 為進行序列化的 model,此外指定 id 為僅供讀取的欄位。完成後到 book/views.py 中新增:

"""
Views for the book APIs.
"""
from rest_framework import viewsets
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from core.models import Book
from book import serializers


class BookViewSet(viewsets.ModelViewSet):
    """View for manage book APIs."""
    serializer_class = serializers.BookSerializer
    queryset = Book.objects.all()
    authentication_classes = [TokenAuthentication]
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        """Retrieve books for authenticated user."""
        return self.queryset.filter(user=self.request.user).order_by('-id')

此處繼承ModelViewSet並指定剛剛創建的BookSerializerserializer_class,預設的查詢資料為所有 book objects。此端點需要授權才能進行操作,所以記得加上之前的授權方法。下方的功能是只回傳該使用者上傳的物件。完成後創建urls.py並加入:

"""
URL mappings for the book app.
"""
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from book import views

router = DefaultRouter()
router.register('books', views.BookViewSet)


app_name = 'book'

urlpatterns = [
    path('', include(router.urls)),
]

這邊使用router = DefaultRouter()來自動創建 CRUD 所需的 urls,創建完成後註冊router.register('books', views.BookViewSet)。最後加進 urlpatterns 中。完成後進入 rest_api/urls.py 中加入 book 中的 urls:

urlpatterns = [
    # ...
    path('api/book/', include('book.urls')),
]

完成後,執行伺服器的時候就可以看到所有 book API 的端點顯示在 Swagger 頁面上,像這樣:

結語

功能的部分尚未實作完畢,因此照目前裝況去測試某些端點時會發生錯誤。明天就來把功能都做完,掰掰。


上一篇
Day 25 - 中場暫停(三) APIView vs ViewSets
下一篇
Day 27 - 製作 API (六) 完成 Book API 功能
系列文
轉職新手學 Django 及 DRF30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言