drf框架

drf框架

」「」接口:
接口規範:
drf的生命週期:
序列化組件:
三大認證:過濾,刪選,排序組件
請求,響應,解析,異常
jwt:json web tooken

「」「
"""
http協議(非安全的,速度快):基於tcp之上的應用層協議
    應用層協議-
    如何交互的規範==請求與響應規範:首行 - 頭 - 體
    特色:無狀態.無鏈接,因此的請求都是從客戶端到服務端,ssl(安全加密機制https)
    
wsgi協議:
原生的django啓動項目。啓動了server socket -wsgiref -uWSGI(項目上線,換了底層的socket,支持併發量高的)
    規定數據的解析方式:get數據,post數據 =>request=>回調的視圖函數
    返回響應對象:HTTPResponse類對象,redirct,JsonPonse,render(4)
        返回的內容是有數據的,且還有響應狀態碼,
    
    """

restful接口規範

"""
1>通常都採用安全協議(接口都是操做數據的):https

2>提現接口的關鍵字:api
    https://api.oldboy.com
    
3>接口操做的數據稱之爲資源:採用資源名稱的複數
    https://api.oldboy.com/books
    
4>接口連接中不出現操做資源的動詞,經過請求方式來決定操做資源的動做
    https://api.oldboy.com/books/
    get:獲取因此
    post:增長一個
    https://api.oldboy.com/books/(?P<pk>)/
    get:獲取一個
    put:總體修改一個(patch局部修改一個)
    delete:刪除一個
    
5>資源數據有多版本時,接口能夠作版本控制,爲何有兩種版本(需求請求不一樣,接口有不一樣的版本響應)
    https://api.oldboy.com/books/v1/
    https://api.oldboy.com/v2/books/
    丟在資源以前以後均可以
    
6>資源響應的限制條件:篩選、排序、限制...
    https://api.oldboy.com/books/?publish=1&ordering=-price&limit=3
    
7>響應狀態碼
    網絡狀態碼:2xx | 3xx | 4xx | 5xx
    數據狀態碼(約定的):0 | 1 | 2
    {
        'status': 1,
    }
    -- SUCCESS(0, "查詢成功")
    -- NODATA(1, "非正確,無數據,顯示基本信息")
    -- FEAILED(2, "查詢失敗")
    
8>響應結果的信息描述:
    {
        'status': 1,
        'msg': 'login failed'
    }

9>響應的結果:get全部:全部資源 | get一個:一個資源 | post、put、patch:新增、修改的資源 | delete:不作任何返回
    {
        'status': 0,
        'msg': 'ok',
        'results': [登陸的用戶對象序列化結果]
    }
    
10>響應結果中有二次資源(用戶頭像:圖片連接,用戶詳情:詳情接口)
    要代表請求二次資源的接口

注:經過 接口文檔 告訴前臺傳遞的必要和選填參數
"""

百度測試接口

安裝postman
https://www.getpostman.com/downloads/
測試接口
method: GET
url: https://api.map.baidu.com/place/v2/search
params:
ak: 6E823f587c95f0148c19993539b99295
region: 上海
query: 肯德基
output: json

原生Django實現接口

建立Django項目並設置默認app名爲api,完成路由分發
# 主路由
fromdjango.conf.urlsimporturl, include
fromdjango.contribimportadmin
urlpatterns= [
   url(r'^admin/', admin.site.urls),
   url(r'^api/', include('api.urls')),
]

# api應用下的子路由
fromdjango.conf.urlsimporturl
from. importviews
urlpatterns= [
   # as_view() 本質拿到 view函數地址,
   # view內部經過dispatch分發請求給具體的(get|post|delete)方法處理請求
   # 處理完後的響應結果會一層層返回
   url(r'^books/$', views.BookView.as_view()),
   url(r'^books/(?P<pk>.*)/$', views.BookView.as_view()),
]
模型層:models.py
fromdjango.dbimportmodels
classBook(models.Model):
   name= models.CharField(max_length=64)
   price= models.DecimalField(max_digits=5, decimal_places=2)
   classMeta:
       db_table= 'old_boy_book'
       verbose_name= '書籍'
       verbose_name_plural= verbose_name
   def__str__(self):
       returnself.name
數據庫遷移
>: python manage.py makemigrations
>: python manage.py migrate
後臺管理:admin.py
fromdjango.contribimportadmin
from. importmodels
admin.site.register(models.Book)
admin.site.register(models.User)

# 建立超級用戶
# >: python manage.py createsuperuser
視圖層:views.py
fromdjango.viewsimportView
fromdjango.httpimportJsonResponse
from. importmodels
classBookView(View):
   defget(self, request, *args, **kwargs):
       pk= kwargs.get('pk')
       ifpk:  # 經過是否有主鍵決定獲取單個或是所有資源
           book_dic_list= models.Book.objects.filter(pk=pk).values('name', 'price')
           ifnotbook_dic_list:
               returnJsonResponse({
                   'status': 2,
                   'msg': 'pk值有誤',
                   'results': {}
              })
           returnJsonResponse({
               'status': 0,
               'msg': 'ok',
               'results': book_dic_list[0]
          })

       book_dic_list= models.Book.objects.all().values('name', 'price')
       ifnotbook_dic_list:
           returnJsonResponse({
               'status': 2,
               'msg': '無數據',
               'results': {}
          })
       returnJsonResponse({
           'status': 0,
           'msg': 'ok',
           'results': list(book_dic_list)
      })

視圖層回顧

視圖:models.py
classUser(models.Model):
   SEX_CHOICES= [
      (0, '男'),
      (1, '女'),
      (2, '哇塞')
  ]
   username= models.CharField(max_length=64)
   password= models.CharField(max_length=64)
   sex= models.IntegerField(choices=SEX_CHOICES, default=0)
   # 須要配置media工做目錄與路由
   icon= models.ImageField(upload_to='icon', default='/icon/default.png')
   classMeta:
       db_table= 'old_boy_user'
       verbose_name= '用戶'
       verbose_name_plural= verbose_name

   def__str__(self):
       returnself.username
media工做目錄:settings.py
# MEDIA_URL = '/media/'
MEDIA_ROOT= os.path.join(BASE_DIR, 'media')
路由:主urls.py
fromdjango.conf.urlsimporturl, include
fromdjango.contribimportadmin

fromdjango.views.staticimportserve
fromdjango.confimportsettings
urlpatterns= [
   url(r'^admin/', admin.site.urls),
   url(r'^api/', include('api.urls')),
   url(r'^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT})
]

drf框架

安裝
>: pip3 install djangorestframework
配置:settings.py
# 註冊drf app
NSTALLED_APPS= [
   # ...
   'rest_framework',
]
特色:
# 具體功能在具體模塊下
fromrest_framework.requestimportRequest
fromrest_framework.responseimportResponse
fromrest_framework.exceptionsimportAPIException
fromrest_framework.filtersimportOrderingFilter
fromrest_framework.viewsimportAPIView
fromrest_framework.paginationimportPageNumberPagination
fromrest_framework.settingsimportAPISettings

# 自定義drf配置 - 在本身的settings.py
REST_FRAMEWORK= {
   # 自定義修改drf的配置們
}

原生Django CBV 源碼分析:View

"""
1)as_view()是入口,獲得view函數地址
2)請求來了調用view函數,內部調用dispatch函數完成請求分發
3)dispatch函數將請求方式映射成視圖類的同名方法,完成請求的處理,獲得相應
4)再將相應的結果一層層返回
"""

drf CBV 源碼分析:APIView

"""
1)as_view()是入口,獲得view函數地址,在範圍view函數地址時局部禁用csrf認證
2)請求來了調用view函數,內部調用(APIView類的)dispatch函數完成請求分發
3)dispatch函數 二次封裝request、完成三大認證後,再將請求方式映射成視圖類的同名方法,完成請求的處理,獲得相應,再對相應作渲染處理
4)再將相應的結果一層層返回
"""

響應渲染模塊:json和瀏覽器接口頁面

# 入口:APIView類的dispatch函數
self.response= self.finalize_response(request, response, *args, **kwargs)
->
neg= self.perform_content_negotiation(request, force=True)
->
renderers= self.get_renderers()
->
self.renderer_classes
->
APISetting:DEFAULT_RENDERER_CLASSES
局部配置
fromrest_framework.viewsimportAPIView
fromrest_framework.responseimportResponse

fromrest_framework.renderersimportJSONRenderer
fromrest_framework.renderersimportBrowsableAPIRenderer
classUserAPIView(APIView):
   # 局部配置:只有該視圖類起做用
   renderer_classes= [JSONRenderer]  # 只提供JSON數據渲染
   pass
全局配置
# drf配置
REST_FRAMEWORK= {
   # 響應的渲染模塊
   'DEFAULT_RENDERER_CLASSES': [
       'rest_framework.renderers.JSONRenderer',
       'rest_framework.renderers.BrowsableAPIRenderer',
  ],
}

請求數據解析模塊:json、form-data、urlencoding

# 入口:APIView類的dispatch函數
request= self.initialize_request(request, *args, **kwargs)
->
parsers=self.get_parsers()
->
self.parser_classes
->
APISetting:DEFAULT_PARSER_CLASSES
局部配置
from rest_framework.views import APIView
from rest_framework.response import Response

from rest_framework.parsers import JSONParser
from rest_framework.parsers import FormParser
from rest_framework.parsers import MultiPartParser
class UserAPIView(APIView):
    # 局部配置:只有該視圖類起做用
    parser_classes = [JSONParser]  # 只提供JSON解析
    pass
全局配置
# drf配置
REST_FRAMEWORK= {
   # 響應的渲染模塊
   'DEFAULT_RENDERER_CLASSES': [
       'rest_framework.renderers.JSONRenderer',
       'rest_framework.renderers.BrowsableAPIRenderer',
  ],
   # 請求數據解析模塊
   'DEFAULT_PARSER_CLASSES': [
       'rest_framework.parsers.JSONParser',  # 'application/json'
       'rest_framework.parsers.FormParser',  # 'application/x-www-form-urlencoded'
       'rest_framework.parsers.MultiPartParser' # multipart/form-data
  ],
}
請求數據解析位置
# 請求的數據包:均解析到 request.data 中
# 請求的?文件參數:均解析到 request.query_params 中

響應模塊

# 響應能夠設置響應數據、響應網絡狀態碼、響應頭、響應數據類型等
data= {
   'status': 0,
   'msg': 'get ok',
   'results': [],
   'token': '123.12321.231'
}
returnResponse(
   data=data,
   status=status.HTTP_200_OK,
   headers={'Token': '123as.masd21.asd213sd'},
   content_type='application/json' # 默認就是application/json
)
相關文章
相關標籤/搜索