python - Django - restframework 簡單使用 和 組件
阿新 • • 發佈:2019-02-27
n) nbsp tle false 方式 price led char dom
FBV 和 CBV
CBV 通過函數調用方法
FBV 通過類調用方法
其本質上都是 CBV
但是 FBV 內部封裝了關於 method 的方法,由於基本上都是前端的請求,所有像GET,POST等方法用的頻繁,
而FBV將這些方法封裝了起來,使得開發時更便捷了許多,所以FBV更適合寫接口
###### 標準的 ######
2.1 fbv方式請求的過程
用戶發送url請求,Django會依次遍歷路由映射表中的所有記錄,一旦路由映射表其中的一條匹配成功了,
就執行視圖函數中對應的函數名,這是fbv的執行流程
2.2 cbv方式請求的過程
當服務端使用cbv模式的時候,用戶發給服務端的請求包含url和method,這兩個信息都是字符串類型
服務端通過路由映射表匹配成功後會自動去找dispatch方法,然後Django會通過dispatch反射的方式找到類中對應的方法並執行
類中的方法執行完畢之後,會把客戶端想要的數據返回給dispatch方法,由dispatch方法把數據返回經客戶端
一:下載
pip install djangorestframewrok
二:Views
# restframework 常用的類 from rest_framework.views import APIView from rest_framework.generics import GenericAPIViewfrom rest_framework.viewsets import GenericViewSet from rest_framework.viewsets import ModelViewSet from rest_framework.response import Response
寫法1:
-- from rest_framework import serializers (1)和 models 表中的字段對應 (使用模塊:serializers.Serializer) (2)全部字段直接寫(使用模塊:serializers.ModelSerializer)class Meta: model = models.Book fields = ‘__all__‘ (3)使用時需要調用 BookModelSerializers(queryset/data,many=True/False) 註:當需要返回一個 queryset 的時候必須加 many=True 這個參數,單條數據則不用 -- ----------Url---------- from app01 import views re_path(‘book/$‘,views.BookView.as_view()) ----------View---------- from rest_framework import serializers class BookModelSerializers(serializers.ModelSerializer): title = serializers.CharField() price = serializers.CharField() publish = serializers.CharField() from rest_framework.views import APIView from rest_framework.views import Response # 更新操作: def put(self,request,pk): shop = models.Shop.objects.filter(pk=pk).first() bs = ShopSerializers(shop,data=request.data) if bs.is_valid(): # 判斷數據是否有誤 print(‘bs: ‘,bs) bs.save() # 相當於調用了 updata方法 return Response(bs.data) # 返回 數據 else: return Response(bs.errors) # 添加操作: ps = PublishSerializers(data=request.data) if ps.is_valid(): ps.save() # create # 查詢操作: class BookView(APIView): def get(self,request): book_list = models.Book.objects.all() serializers = BookModelSerializers(book_list,many=True) return Response(serializers.data) # 刪除操作: def delete(self,request,pk): models.Shop.objects.filter(pk=pk).delete() return Response()
寫法2:
-- (a) (1)mixins 模塊中有 List,Create,Put...方法可以直接使用 (2)generics 主要作用還是調用 APIView 中的 -- ----------Url---------- from app01 import views re_path(‘book/$‘,views.BookView.as_view()) ----------View (a)---------- from rest_framework import mixins from rest_framework import generics from rest_framework import serializers from rest_framework import serializers class BookModelSerializers(serializers.ModelSerializer): title = serializers.CharField() price = serializers.CharField() publish = serializers.CharField() class AuthorView(mixins.ListModelMixin,generics.GenericAPIView): queryset = models.Author.objects.all() # 必須有的參數 :queryset serializer_class = AuthorModelSerializers # 必須有的參數 :serializer_class def get(self,request,*args,**kwargs): return self.list(request,*args,**kwargs) -- (b) (1)繼承 generics.RetrieveUpdateDestroyAPIView 將上面的 mixins generics 全部封裝成了一個模塊 -- ----------View (b)---------- 比上面簡單一點 class UserView(generics.RetrieveUpdateDestroyAPIView): queryset = models.User.objects.all() serializer_class = UserModelSerializers
寫法三:
-- (1) as_view({參數}) 中傳的參數是必須的,參數的名稱還是固定的, 可根據需求來限定哪個url配定哪個參數 (2) view 中 的變量名也是固定的,不能改變, 當執行到某個父類的方法的時候,就會需要這兩個參數 queryset -- queryset serializer_class -- ----------Url---------- from app01 import views re_path(‘book/$‘, views.Book.as_view({‘get‘: ‘list‘, ‘post‘: ‘create‘})), re_path(‘book/(?P<pk>\d+)/$‘, views.Book.as_view({‘get‘: ‘retrieve‘, ‘put‘: ‘update‘,‘delete‘:‘destroy‘})), ----------View---------- from rest_framework import viewsets class Book(viewsets.ModelViewSet): queryset = models.Book.objects.all() serializer_class = BookModelSerializers
四:認證組件
---------- View(局部認證) ---------- -- (1) BaseAuthentication 模塊中 有倆個方法(authenticate , authenticate_header) 註:這倆個方法也是固定名字,兩個必須寫上,一個都不能少,否則報錯 ! 模塊中這兩個方法都是返回空的,但是執行的時候當前函數就將 兩個方法覆蓋了,也就是少些一個 authenticate_header (2) 創建一個 返回 隨機字符的 token (3) update_or_create -- 如果有就更新,如果沒有就創建 -- # 認證 組件 from rest_framework import exceptions from rest_framework.authentication import BaseAuthentication from app01 import models class TokenAuth(BaseAuthentication): # 這個方法直接寫在一個文件中 def authenticate(self,request): token = request.GET.get(‘token‘) # 獲取 token token_obj = models.Token.objects.filter(token=token).first() # 驗證 token 是否匹配 if not token_obj: raise exceptions.AuthenticationFailed(‘驗證失敗‘) else: return token_obj.user.name,token_obj.token # 返回一個 登陸校驗判斷 的隨機字符串 def get_random_str(user): import hashlib,time ctime = str(time.time()) # 當前時間字符串 md5 = hashlib.md5(bytes(user,encoding=‘utf8‘)) # md5 加密,加鹽 md5.update(bytes(ctime,encoding=‘utf8‘)) # 將字符串進行拼接 #md5.digest() 二進制 #md5.hexdigest() 十六進制 return md5.hexdigest() # 返回一個 十六進制 的加密隨機字符 # 登陸驗證 class LoginView(APIView): authentication_classes = [TokenAuth] def post(self,request): name = request.data.get(‘name‘) # 獲取用戶名 pwd = request.data.get(‘pwd‘) # 獲取密碼 user = models.User.objects.filter(name=name,pwd=pwd).first() # 數據庫校驗 res = {‘code‘:0,‘msg‘:None} if user: random_str = get_random_str(user.name) token = models.Token.objects.update_or_create(user=user,defaults={‘token‘:random_str}) # 在數據庫生成 token res[‘token‘] = random_str res[‘code‘] = 1 res[‘msg‘] = ‘驗證成功‘ else: res[‘msg‘] = ‘驗證失敗‘ import json return Response(json.dumps(res)) ---------- View(全局認證) ---------- (1) settings 中配置 認證組件位置: # 全局認證組件 REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.TokenAuth",] } (2) 這樣就不用寫 authentication_classes = [TokenAuth] (3) 如果哪個方法不需要認證的話 只需要 authentication_classes = [] 將列表設為空
五:權限組件
# 權限組件 class SvipPermission(object): # 這個方法直接寫在一個文件中 message = "只有超級用戶才能訪問" def has_permission(self,request,view): username = request.user user_type = models.User.objects.filter(name=username).first().user_type if user_type == 3: return True # 返回True 則驗證通過 else: return False # 返回False 則驗證不通過
# 只需類下面添加
permission_classes = [SvipPermission] # 權限組件 -- 局部
# 全局認證
REST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES":[‘app01.utils.SvipPermission‘], # 全局權限組件
}
六:解析器 (用於將解析字符格式)
from rest_framework.parsers import JSONParser,FormParser parser_classes = [JSONParser, FormParser] # 局部 (用於將解析字符格式)
七:分頁器 -- 用於調試 restframework 返回的頁面
# 要使用 restframework 自帶的調試數據網頁 需要在 settings 中配置
INSTALLED_APPS = [
‘django.contrib.admin‘,
‘django.contrib.auth‘,
‘django.contrib.contenttypes‘,
‘django.contrib.sessions‘,
‘django.contrib.messages‘,
‘django.contrib.staticfiles‘,
‘app01.apps.App01Config‘,
‘rest_framework‘, # 配置 restframework 組件
]
# 分頁器 from rest_framework.pagination import PageNumberPagination class BookPageNumberPagination(PageNumberPagination): page_size = 1 # 每頁顯示個數 page_query_param = ‘page‘ page_size_query_param = ‘size‘ # 修改當前頁顯示個數 #max_page_size = 2 # 每頁顯示個數限制 class BookView(APIView): def get(self,request): book_list = models.Book.objects.all() # 分頁器 pnp = BookPageNumberPagination() book_page = pnp.paginate_queryset(book_list,request,self) bs = BookModelSerializers(book_page,many=True,context={‘request‘: request}) return Response(bs.data)
python - Django - restframework 簡單使用 和 組件