天天看點

Django開發REST API接口的基本介紹

  • 下面是在Django架構中使用的圖書案例來寫一套支援資料增删改查的REST API接口,來了解REST API的開發
  • 我們這個案例中,以前後端均發送JSON格式資料為基礎。
    • 先定義一個views.py的視圖檔案
    • #因為有時間字段,是以需要先導入datetime擴充包
      from datetimme import datetime
      #實際到視圖是以需要導入Django自帶的View擴充包
      from django.view import View
      #導入django中的響應擴充
      from django.http import JsonResponse
      
      #定義圖書視圖類
      class BookAPIView(View):
          '''
          業務邏輯:查詢所有圖書、增加圖書
          '''
          def get(self,request):
              '''
              查詢所有圖書
              路由:GET    /books/
              '''
              #查詢資料庫得到查詢集:這裡的BookInfo是我們之前定義好的模闆類
              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需要判斷是存在,存放在,傳回路徑,不存在傳回 None
                      'image':book.image.url if book.image else ''   
          
                  })
              return JsonResponse(book_list,safe=False)    
              #對safe的說明,我們傳過去的book_list是一個list格式,在前端json支援{}也支援[]格式
              #但是django中認為[]的json格式是不安全的會進行校驗,是以把safe=False,不進行校驗
          def post(self,request):
              '''
              新增圖書
              路由:POST    /books/
              '''
              #查詢到的資料是二進制
              json_bytes = request.body
              #需要進行解碼,轉成字元串
              json_str = json_bytes.decode()
              #在把字元串轉換成json字典
              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)
                 
      擷取單個圖書資訊、修改圖書資訊和删除圖書資訊都需要指定id是以這三項單獨定一個類視圖
    • 代碼如下:
      class BookAPIView(View):
          
          def get(self,request,pk):
          '''
          擷取單個圖書資訊 
          路由:GET     /books/<pk>/
          '''
          
          #擷取單個資料可能或回去不到,會報錯,是以需要tyr
          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檔案
      #需要導入路由擴充
      from django.conf.urls import url
      
      #導入視圖
      from . import views
      
      #配置路由
      urlpatterns = [
          url(r'^books/$', views.BooksAPIVIew.as_view()),
          url(r'^books/(?P<pk>\d+)/$', views.BookAPIView.as_view())
      ]
      #類視圖不能直接作為路由,是以需要加入 as_view(),把它當做一個視圖函數去使用
                 
      當然我還還需要在總路由下面設定路由綁定到子路由
    • 測試:我們可以使用Postman測試上述接口

繼續閱讀