rest-framework框架 -- 解析器、分頁、路由
阿新 • • 發佈:2018-04-11
表示 color 組件 elf post data ... rest art rmp
解析器
:reqest.data取值的時候才執行
對請求的數據進行解析:是針對請求體進行解析的。表示服務器可以解析的數據格式的種類
django中的發送請求
#如果是這樣的格式發送的數據,在POST裏面有值 Content-Type: application/url-encoding..... request.body request.POST #如果是發送的json的格式,在POST裏面是沒有值的,在body裏面有值,可通過decode,然後loads取值 Content-Type: application/json..... request.body request.POST
關於decode、encode 瀏覽器發送過來是字節需要先解碼 ---> decode 如:s=‘中文‘ 如果是在utf8的文件中,該字符串就是utf8編碼,如果是在gb2312的文件中,則其編碼為gb2312。這種情況下,要進行編碼轉換,都需要先用 decode方法將其轉換成unicode編碼,再使用encode方法將其轉換成其他編碼。通常,在沒有指定特定的編碼方式時,都是使用的系統默認編碼創建的代碼文件。 如下: s.decode(‘utf-8‘).encode(‘utf-8‘) decode():是解碼 --->把字節變成字符串 encode()是編碼---->把字符串變成字節
django只解析兩種形式
1:導入django的類 from django.core.handlers.wsgi import WSGIRequest 2: class WSGIRequest(http.HttpRequest): def _get_post(self): if not hasattr(self, ‘_post‘): self._load_post_and_files() return self._post 3: # self._load_post_and_files()從這裏找到django解析的方法def _load_post_and_files(self): """Populate self._post and self._files if the content-type is a form type""" if self.method != ‘POST‘: self._post, self._files = QueryDict(encoding=self._encoding), MultiValueDict() return if self._read_started and not hasattr(self, ‘_body‘): self._mark_post_parse_error() return if self.content_type == ‘multipart/form-data‘: if hasattr(self, ‘_body‘): # Use already read data data = BytesIO(self._body) else: data = self try: self._post, self._files = self.parse_file_upload(self.META, data) except MultiPartParserError: # An error occurred while parsing POST data. Since when # formatting the error the request handler might access # self.POST, set self._post and self._file to prevent # attempts to parse POST data again. # Mark that an error occurred. This allows self.__repr__ to # be explicit about it instead of simply representing an # empty POST self._mark_post_parse_error() raise elif self.content_type == ‘application/x-www-form-urlencoded‘: self._post, self._files = QueryDict(self.body, encoding=self._encoding), MultiValueDict() else: self._post, self._files = QueryDict(encoding=self._encoding), MultiValueDict() 從上面的 if self.content_type == ‘multipart/form-data‘:和 self.content_type == ‘application/x-www-form-urlencoded‘: 可以知道django只解析urlencoded‘和form-data這兩種類型
傳json數據默認為urlencoded這種解析
到request。body取原數據過來json數據時,django解析步驟---->需要我們自己操作
1:取到的數據是字節
需要先解碼decode():是解碼 --->把字節變成字符串
request。body。decode("utf8")
json.loads(request。body。decode("utf8"))
為了這種情況下每次都要decode,loads,顯得麻煩,所以才有的解析器。彌補了django的缺點
客戶端: Content-Type: application/json ‘{"name":"alex","age":123}‘ 服務端接收: 讀取客戶端發送的Content-Type的值 application/json parser_classes = [JSONParser,FormParser] #表示服務器可以解析的數據格式的種類 media_type_list = [‘application/json‘,‘application/x-www-form-urlencoded‘] 如果客戶端的Content-Type的值和 application/json 匹配:JSONParser處理數據 如果客戶端的Content-Type的值和 application/x-www-form-urlencoded 匹配:FormParser處理數據 配置: 單視圖: class UsersView(APIView): parser_classes = [JSONParser,] 全局配置: REST_FRAMEWORK = { ‘VERSION_PARAM‘:‘version‘, ‘DEFAULT_VERSION‘:‘v1‘, ‘ALLOWED_VERSIONS‘:[‘v1‘,‘v2‘], # ‘DEFAULT_VERSIONING_CLASS‘:"rest_framework.versioning.HostNameVersioning" ‘DEFAULT_VERSIONING_CLASS‘:"rest_framework.versioning.URLPathVersioning", ‘DEFAULT_PARSER_CLASSES‘:[ ‘rest_framework.parsers.JSONParser‘, ‘rest_framework.parsers.FormParser‘, ] } class UserView(APIView): def get(self,request,*args,**kwargs): return Response(‘ok‘) def post(self,request,*args,**kwargs): print(request.data) #以後取值就在這裏面去取值 return Response(‘...‘) 具體講解具體講解
rest-framework
在rest-framework中 是以利用Request類進行數據解析
1:找到apiview class APIView(View): # The following policies may be set at either globally, or per-view. renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES parser_classes = api_settings.DEFAULT_PARSER_CLASSES # 解析器 2:找api_settings沒有定義找默認 renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES 3:. api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS) 4:DEFAULTS DEFAULTS = { # Base API policies # 自帶的解析器 ‘DEFAULT_PARSER_CLASSES‘: ( ‘rest_framework.parsers.JSONParser‘, # 解析json數據 ‘rest_framework.parsers.FormParser‘, # from數據 ‘rest_framework.parsers.MultiPartParser‘ # 多數據 ),
例如
# 利用rest-framework的解析器 from rest_framework.parsers import JSONParser, FormParser class PublishView(generics.ListCreateAPIView): parser_classes = [FormParser] # 自定義用哪些解析器來解析數據 queryset = Publish.objects.all() serializer_class = PublishSerializers
全局視圖
REST_FRAMEWORK={ "DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",], "DEFAULT_PERMISSION_CLASSES":["app01.service.permissions.SVIPPermission",], "DEFAULT_THROTTLE_CLASSES":["app01.service.throttles.VisitThrottle",], "DEFAULT_THROTTLE_RATES":{ "visit_rate":"5/m", }, "DEFAULT_PARSER_CLASSES":[‘rest_framework.parsers.FormParser‘,] }
分頁
試問如果當數據量特別大的時候,你是怎麽解決分頁的?
- 方式a、記錄當前訪問頁數的數據id
- 方式b、最多顯示120頁等
- 方式c、只顯示上一頁,下一頁,不讓選擇頁碼,對頁碼進行加密
1:全局分頁
view。py: class PublishView(generics.ListCreateAPIView): # parser_classes = [FormParser] # 自定義用哪些解析器來解析數據 queryset = Publish.objects.all() serializer_class = PublishSerializers # 序列化 def get(self,request,*args,**kwargs): publish_list = Publish.objects.all() # 構建分頁器對象 pnp = PageNumberPagination() # 分完頁的數據 pager_pulisher = pnp.paginate_queryset(queryset=publish_list,request=request,view=self) print(pager_pulisher) ps = PublishSerializers(pager_pulisher,many=True) return Response(ps.data) setting: REST_FRAMEWORK={ "DEFAULT_AUTHENTICATION_CLASSES":["api.service.auth.MyAuthentication"], # 認證組件 "DEFAULT_PERMISSION_CLASSES":["api.service.permission.SVIPPermission"], # 權限組件 "DEFAULT_THROTTLE_CLASSES":["api.service.throttles.VisitThrottle"], # 頻率組件 # SimpleRateThrottle "DEFAULT_THROTTLE_RATES":{ "visit_rate":"5/m," }, # 分頁器參數 "PAGE_SIZE":2 #每頁顯示的數據 }
局部及部分參數
# 自定義局部分頁 class MyPageNumberPagination(PageNumberPagination): page_size = 2 # 每頁顯示2條數據 page_query_param = "page_num" # http://127.0.0.1:8000/publishes/?page_num=2 size = 3 # 從參數控制每頁顯示幾條數據 max_page_size = 5 # 最多顯示5條數據 class PublishView(generics.ListCreateAPIView): # parser_classes = [FormParser] # 自定義用哪些解析器來解析數據 queryset = Publish.objects.all() serializer_class = PublishSerializers # 序列化 def get(self,request,*args,**kwargs): publish_list = Publish.objects.all() # 構建分頁器對象 pnp = PageNumberPagination() # 分完頁的數據 pager_pulisher = pnp.paginate_queryset(queryset=publish_list,request=request,view=self) print(pager_pulisher) ps = PublishSerializers(pager_pulisher,many=True) return Response(ps.data)
rest-framework框架 -- 解析器、分頁、路由