04.開發REST 介面

平仄平仄平平仄發表於2020-06-18

使用Django開發REST 介面

我們以在Django框架中使用的圖書英雄案例來寫一套支援圖書資料增刪改查的REST API介面,來理解REST API的開發。

在此案例中,前後端均傳送JSON格式資料。

# views.py

from datetime import datetime

class BooksAPIVIew(View):
    """
    查詢所有圖書、增加圖書
    """
    def get(self, request):
        """
        查詢所有圖書
        路由:GET /books/
        """
        queryset = BookInfo.objects.all()
        book_list = []
        for book in queryset:
            book_list.append({
                'id': book.id,
                'btitle': book.btitle,
                'bpub_date': book.bpub_date,
                'bread': book.bread,
                'bcomment': book.bcomment,
                'image': book.image.url if book.image else ''
            })
        return JsonResponse(book_list, safe=False)

    def post(self, request):
        """
        新增圖書
        路由:POST /books/
        """
        json_bytes = request.body
        json_str = json_bytes.decode()
        book_dict = json.loads(json_str)

        # 此處詳細的校驗引數省略

        book = BookInfo.objects.create(
            btitle=book_dict.get('btitle'),
            bpub_date=datetime.strptime(book_dict.get('bpub_date'), '%Y-%m-%d').date()
        )

        return JsonResponse({
            'id': book.id,
            'btitle': book.btitle,
            'bpub_date': book.bpub_date,
            'bread': book.bread,
            'bcomment': book.bcomment,
            'image': book.image.url if book.image else ''
        }, status=201)


class BookAPIView(View):
    def get(self, request, pk):
        """
        獲取單個圖書資訊
        路由: GET  /books/<pk>/
        """
        try:
            book = BookInfo.objects.get(pk=pk)
        except BookInfo.DoesNotExist:
            return HttpResponse(status=404)

        return JsonResponse({
            'id': book.id,
            'btitle': book.btitle,
            'bpub_date': book.bpub_date,
            'bread': book.bread,
            'bcomment': book.bcomment,
            'image': book.image.url if book.image else ''
        })

    def put(self, request, pk):
        """
        修改圖書資訊
        路由: PUT  /books/<pk>
        """
        try:
            book = BookInfo.objects.get(pk=pk)
        except BookInfo.DoesNotExist:
            return HttpResponse(status=404)

        json_bytes = request.body
        json_str = json_bytes.decode()
        book_dict = json.loads(json_str)

        # 此處詳細的校驗引數省略

        book.btitle = book_dict.get('btitle')
        book.bpub_date = datetime.strptime(book_dict.get('bpub_date'), '%Y-%m-%d').date()
        book.save()

        return JsonResponse({
            'id': book.id,
            'btitle': book.btitle,
            'bpub_date': book.bpub_date,
            'bread': book.bread,
            'bcomment': book.bcomment,
            'image': book.image.url if book.image else ''
        })

    def delete(self, request, pk):
        """
        刪除圖書
        路由: DELETE /books/<pk>/
        """
        try:
            book = BookInfo.objects.get(pk=pk)
        except BookInfo.DoesNotExist:
            return HttpResponse(status=404)

        book.delete()

        return HttpResponse(status=204)
# urls.py

urlpatterns = [
    url(r'^books/$', views.BooksAPIVIew.as_view()),
    url(r'^books/(?P<pk>\d+)/$', views.BookAPIView.as_view())
]

測試

使用Postman測試上述介面

1) 獲取所有圖書資料

GET 方式訪問 http://127.0.0.1:8000/books/, 返回狀態碼200,資料如下

[
    {
        "id": 1,
        "btitle": "射鵰英雄傳",
        "bpub_date": "1980-05-01",
        "bread": 12,
        "bcomment": 34,
        "image": ""
    },
    {
        "id": 2,
        "btitle": "天龍八部",
        "bpub_date": "1986-07-24",
        "bread": 36,
        "bcomment": 40,
        "image": ""
    },
    {
        "id": 3,
        "btitle": "笑傲江湖",
        "bpub_date": "1995-12-24",
        "bread": 20,
        "bcomment": 80,
        "image": ""
    },
    {
        "id": 4,
        "btitle": "雪山飛狐",
        "bpub_date": "1987-11-11",
        "bread": 58,
        "bcomment": 24,
        "image": ""
    },
    {
        "id": 5,
        "btitle": "西遊記",
        "bpub_date": "1988-01-01",
        "bread": 10,
        "bcomment": 10,
        "image": "booktest/xiyouji.png"
    },
    {
        "id": 6,
        "btitle": "水滸傳",
        "bpub_date": "1992-01-01",
        "bread": 10,
        "bcomment": 11,
        "image": ""
    },
    {
        "id": 7,
        "btitle": "紅樓夢",
        "bpub_date": "1990-01-01",
        "bread": 0,
        "bcomment": 0,
        "image": ""
    }
]

2)獲取單一圖書資料

GET 訪問 http://127.0.0.1:8000/books/5/ ,返回狀態碼200, 資料如下

{
    "id": 5,
    "btitle": "西遊記",
    "bpub_date": "1988-01-01",
    "bread": 10,
    "bcomment": 10,
    "image": "booktest/xiyouji.png"
}

GET 訪問http://127.0.0.1:8000/books/100/,返回狀態碼404

3)新增圖書資料

POST 訪問http://127.0.0.1:8000/books/,傳送JSON資料:

{
    "btitle": "三國演義",
    "bpub_date": "1990-02-03"
}

返回狀態碼201,資料如下

{
    "id": 8,
    "btitle": "三國演義",
    "bpub_date": "1990-02-03",
    "bread": 0,
    "bcomment": 0,
    "image": ""
}

4)修改圖書資料

PUT 訪問http://127.0.0.1:8000/books/8/,傳送JSON資料:

{
    "btitle": "三國演義(第二版)",
    "bpub_date": "1990-02-03"
}

返回狀態碼200,資料如下

{
    "id": 8,
    "btitle": "三國演義(第二版)",
    "bpub_date": "1990-02-03",
    "bread": 0,
    "bcomment": 0,
    "image": ""
}

5)刪除圖書資料

DELETE 訪問http://127.0.0.1:8000/books/8/,返回204狀態碼

相關文章