Django_rest_framework_渲染器/解析器/路由控制/分頁

目錄

渲染器html

解析器python

路由控制django

分頁restful

渲染器

簡介

什麼是渲染器

根據 用戶請求URL 或 用戶可接受的類型,篩選出合適的 渲染組件。網絡

渲染器的做用

序列化、友好的展現數據app

渲染器配置

首先要在settins.py中將rest_framework組件加進去ide

 

局部配置渲染器

引入渲染器類,而後將他們做爲一個列表的元素賦值給renderer_classes 配置屬性,以下:post

1
2
3
4
5
6
from  rest_framework.renderers  import  JSONRenderer,BrowsableAPIRenderer
 
class  BookViewSet(APIView):
     renderer_classes  =  [JSONRenderer,BrowsableAPIRenderer]
     def  get( self ,request):
         return  Response( '...' )

BrowsableAPIRenderer的渲染效果以下url

 

1
JSONRenderer類的就是隻渲染數據,以下:

 

能夠看到,只是簡單的數據展現spa

全局配置渲染器

在setting.py文件中加入以下配置:

1
2
3
4
5
REST_FRAMEWORK  =  {
     'DEFAULT_RENDERER_CLASSES' :[ 'rest_framework.renderers.JSONRenderer' , 'rest_framework.renderers.BrowsableAPIRenderer' ,],
 
...
}

 

解析器

咱們都知道,網絡傳輸數據只能傳輸字符串格式的,若是是列表、字典等數據類型,須要轉換以後才能使用

可是咱們以前的rest_framework例子都沒有轉換就直接可使用了,這是由於rest_framework有一套解析器,

默認他會幫咱們轉換3種類型的數據,分別是,JSONParser,FormParser,MultiPartParser

局部解析器

若是咱們須要轉換其餘數據,須要在視圖類裏配置parser_classes參數,以下:

1
2
from  rest_framework.parsers  import  JSONParser,FormParser,MultiPartParser,FileUploadParser
parser_classes  =  [JSONParser,FormParser,FileUploadParser]

全局解析器

REST_FRAMEWORK={
    "DEFAULT_PARSER_CLASSES":['rest_framework.parsers.FormParser',]
}

路由控制

咱們以前在寫例子的時候,視圖類已經封裝到最精簡版本了,可是url變的比以前複雜了,以下:

1
2
url(r '^publishes/$' , views.PublishViewSet.as_view({ 'get' : 'list' , 'post' : 'create' })),
url(r '^publishes/(?P<pk>\d+)/$' , views.PublishViewSet.as_view({ 'get' : 'retrieve' , 'put' : 'update' , 'delete' : 'destroy' , 'patch' : 'partial_update' })),

  上面只是一個視圖類對應的url,若是項目作的很大,那麼url會變的很是臃腫,

而rest_framework給咱們封裝了一種自動註冊url的功能,格式以下:

1
2
3
4
5
6
7
8
9
10
11
from  django.conf.urls  import  url
from  django.contrib  import  admin
from  app01  import  views
 
from  django.conf.urls  import  include
from  rest_framework  import  routers
 
# 實例化一個routers對象
routers  =  routers.DefaultRouter()
# 往對象裏註冊(添加)url
routers.register( 'publishes' ,views.PublishViewSet)

  而後,在urlpatterns中添加已經註冊的url(在routers.urls裏),以下:

1
url(r'',include(routers.urls))

  完整版的urlpatterns配置

1
2
3
4
5
6
7
8
9
10
11
urlpatterns  =  [
     url(r '^admin/' , admin.site.urls),
 
     url(r '^login/' , views.Login.as_view()),
 
     url(r '^authors/$' , views.AuthorsView.as_view()),
     url(r '^authors/(\d+)/$' , views.AuthorsDetailView.as_view()),
 
 
     url(r'',include(routers.urls))
]

  這個時候,rest_framework會幫咱們自動添加了4個url,以下圖:

 示例

from django.contrib import admin
from django.urls import path,re_path,include

urlpatterns = [
    re_path("testrestfulframework/",include("testrestfulframework.urls")),
]



####### testrestfulframework.urls.py ###########
from django.urls import path,re_path,include
from testrestfulframework import views
from rest_framework import routers

# 實例化一個routers對象
routers = routers.DefaultRouter()
# 往對象裏註冊(添加)url
routers.register('books', views.BookViewSet)
routers.register('publish', views.PublishViewSet)


urlpatterns = [
    # re_path(r"login/$",views.LoginViewSet.as_view()),
    # re_path(r"books/$",views.BookViewSet.as_view()),
    # re_path(r"books/(?P<pk>\d+)$",views.BookDetailViewSet.as_view()),
    re_path(r'',include(routers.urls)),
]

urls.py
urls.py
from django.db import models


class Book(models.Model):
    title=models.CharField(max_length=32)
    price=models.IntegerField()
    pub_date=models.DateField()
    publish=models.ForeignKey("Publish",on_delete=models.CASCADE)
    authors=models.ManyToManyField("Author")
    def __str__(self):
        return self.title

class Publish(models.Model):
    name=models.CharField(max_length=32)
    email=models.EmailField()
    def __str__(self):
        return self.name

class Author(models.Model):
    name=models.CharField(max_length=32)
    age=models.IntegerField()
    def __str__(self):
        return self.name


class User(models.Model):
    username = models.CharField(max_length=16)
    password = models.CharField(max_length=64)
    role = models.IntegerField(default=1)


class Token(models.Model):
    token = models.CharField(max_length=128)
    user = models.ForeignKey(to=User,on_delete=models.CASCADE)
models.py
# -*- coding:utf-8 -*-
from rest_framework import serializers
from testrestfulframework import models


class BookSerializers(serializers.ModelSerializer):
    # publish = serializers.HyperlinkedIdentityField(
    #     view_name='publish_detail',
    #     lookup_field="publish_id",
    #     lookup_url_kwarg="pk")


    class Meta:
        model = models.Book
        fields = "__all__"
        # depth=1


class PublshSerializers(serializers.ModelSerializer):
    class Meta:
        model = models.Publish
        fields = "__all__"
        # depth = 1

class AuthorSerializers(serializers.ModelSerializer):

    class Meta:
        model = models.Author
        fields = "__all__"
        # depth = 1
serializers.py
from rest_framework import viewsets
from testrestfulframework import models
from testrestfulframework import serializers

class BookViewSet(viewsets.ModelViewSet):
    queryset = models.Book.objects.all()
    serializer_class = serializers.BookSerializers


class PublishViewSet(viewsets.ModelViewSet):
    queryset = models.Publish.objects.all()
    serializer_class = serializers.PublshSerializers
views.py

 

 

 

 

分頁

分頁種類

# service/pagination.py

from
rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination class MyPageNumberPagination(PageNumberPagination): # 定義一個PageNumberPagination的子類 # 如需改變參數,重寫其屬性便可 page_size = 2 #每頁顯示條數 page_query_param = 'page' # url中的參數的key page_size_query_param="size" # 能夠在url中使用size參數臨時改變當頁顯示的數目 max_page_size=10 # 能夠在url中使用size參數臨時改變當頁顯示的數目,可是最大隻能顯示10條。格式:url?size=20 class MyLimitOffsetPagination(LimitOffsetPagination): default_limit =10#一頁默認幾個 limit_query_param = 'limit' #關鍵字後面跟的是一頁顯示幾個 offset_query_param = 'offset'#這個後面跟的是從哪裏顯示 max_limit = 50 #能夠在url中使用limit參數臨時改變當頁顯示的數目,可是最大隻能顯示50條。格式:url?limit=20 class MyCursorPagination(CursorPagination): cursor_query_param = 'cursor'#關鍵字,c page_size =5 #每頁默認的數量 ordering = 'price'#按照id排列 page_size_query_param ='page_size'#每頁顯示的數量

繼承APIView類的視圖中添加分頁

class AuthorsView(APIView):
    def get(self,request):
        '''分頁展現做者列表'''
        author_list = models.Author.objects.all()
        # 分頁
        # 實例化一個本身定義的MyPageNumberPagination對象
        pnp = MyPageNumberPagination()
        # 調用paginate_queryset方法來生成新的author_list
        # 參數分別爲,author_list,request以及當前的視圖
        page_author_list = pnp.paginate_queryset(author_list,request,self)
        # 在將新生成的page_author_list序列化
        auts = serializer.AuthorModelSerializers(page_author_list,many=True)
        return Response(auts.data)
class BaseResponse(object):
    def __init__(self,code=1000,data=None,error=None):
        self.code=code
        self.data=data
        self.error=error


class IndexView(APIView):
    def get(self,request,*args,**kwargs):
        ret=BaseResponse()
        try:
            user_list=models.UserInfo.objects.all()#找到全部的數據項
            p1 = P1()#實例化分頁器,
            page_user_list=p1.paginate_queryset(queryset=user_list,request=request,view=self)#把數據放在分頁器上面
            ser=IndexSerializer(instance=page_user_list,many=True)#序列化數據
            ret.data=ser.data
            ret.next=p1.get_next_link()
        except Exception as e:
            ret.code=1001
            ret.error='xxxx錯誤'
另外一個例子

繼承ModelViewSet類的視圖中添加分頁

若是咱們的視圖繼承了ModelViewSet類,那麼如需分頁的時候,只須要在視圖類中加入配置參數便可,以下:

1
pagination_class  =  MyPageNumberPagination   

  注意:

    一、MyPageNumberPagination類是咱們本身定義的類,見上面一個示例。

    二、pagination_class後面直接跟上類名便可,無需加列表(由於分頁不想其餘組件,分頁只可能有一個)

全局配置分頁屬性

只須要在REST_FRAMEWORK配置中加入 配置屬性的鍵值對便可,以下:

1
2
3
4
REST_FRAMEWORK  =  {
     .....
     "PAGE_SIZE" : 1
}

示例

以上多種方式均實現了3中分頁方式PageNumberPagination,LimitOffsetPagination,CursorPagination,過程略。

 

參考or轉發

http://www.javashuo.com/article/p-kukrfqbc-en.html

http://www.cnblogs.com/fu-yong/p/9067690.html

相關文章
相關標籤/搜索