django rest framework組件下的詳細功能的實現

Django Rest Framework框架組件的執行流程

rest framework組件爲咱們提供了下面的這些功能:
按照HTTP請求的生命週期去記; 先是進入路由,在視圖,進入dispatch()裏面,然
後提供的是版本,權限,認證,頻率,而後從 解析器()裏面取數據,再序列化,分頁,渲染器。

 

1.認證和受權

a. 用戶url傳入的token認證(做爲url的參數傳入)html

from django.conf.urls import url, include
from web.viewsimport TestView

urlpatterns = [
    url(r'^test/', TestView.as_view()),
]
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authentication import BaseAuthentication
from rest_framework.request import Request
from rest_framework import exceptions
from .models import *


class TokenAuth(BaseAuthentication):
	def authenticate(self, request):
		token = request.GET.get("token")
		# request.query_params  ---> request.GET
		token_obj = Token.objects.filter(token=token).first()
		if not token_obj:
			raise exceptions.AuthenticationFailed("驗證失敗123!")
		else:
			return token_obj.user, token_obj.token
		# 返回一個元組 request.user, request.auth

	# def authenticate_header(self, request):
	#     pass
	# 只是咱們繼承了BaseAuthentication的認證組件 就不用寫了。


class TestView(APIView):
    authentication_classes = [TokenAuth, ]
    permission_classes = []

    def get(self, request, *args, **kwargs):
        print(request.user)
        print(request.auth)
        return Response('GET請求,響應內容')

    def post(self, request, *args, **kwargs):
        return Response('POST請求,響應內容')


views.py

 

認證和權限python

from django.conf.urls import url, include
from web.views import TestView

urlpatterns = [
    url(r'^test/', TestView.as_view()),
]
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authentication import BaseAuthentication
from rest_framework.permissions import BasePermission
from rest_framework.request import Request
from rest_framework import exceptions
from .models import *


class TokenAuth(BaseAuthentication):
	def authenticate(self, request):
		token = request.GET.get("token")
		# request.query_params  ---> request.GET
		token_obj = Token.objects.filter(token=token).first()
		if not token_obj:
			raise exceptions.AuthenticationFailed("驗證失敗123!")
		else:
			return token_obj.user.pk, token_obj.token
		# 返回一個元組 request.user, request.auth

	# def authenticate_header(self, request):
	#     pass
	# 只是咱們繼承了BaseAuthentication的認證組件 就不用寫了。

class SVIPPermisson(BasePermission):
	message = "沒有SVIP權限"  # 錯誤信息

	def has_permission(self, request, view):
		if request.user == 1:    # request.user.pk 是從認證組件裏面取的
			return True
		else:
			return False    #沒有權限


class TestView(APIView):
    # 認證的動做是由request.user觸發
    authentication_classes = [TestAuthentication, ]

    # 權限
    # 循環執行全部的權限
    permission_classes = [TestPermission, ]

    def get(self, request, *args, **kwargs):
        # self.dispatch
        print(request.user)
        print(request.auth)
        return Response('GET請求,響應內容')

    def post(self, request, *args, **kwargs):
        return Response('POST請求,響應內容')



views.py

 

全局使用權限和認證,就須要在settings裏面去配置全局信息。web

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "web.utils.TestAuthentication",
    ],
    "DEFAULT_PERMISSION_CLASSES": [
        "web.utils.TestPermission",
    ],
}

settings.py

 

2.用戶訪問次數/頻率限制

a. 基於用戶IP限制訪問頻率數據庫

這種方法是沒法控制的,由於用戶能夠換代理IP,因此沒有徹底的限制。django

from django.conf.urls import url, include
from web.views import TestView

urlpatterns = [
    url(r'^test/', TestView.as_view()),
]

urls.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import time
from rest_framework.views import APIView
from rest_framework.response import Response

from rest_framework import exceptions
from rest_framework.throttling import BaseThrottle
from rest_framework.settings import api_settings

# 保存訪問記錄
RECORD = {
    '用戶IP': [12312139, 12312135, 12312133, ]
}


class TestThrottle(BaseThrottle):
    ctime = time.time

    def get_ident(self, request):
        """
        根據用戶IP和代理IP,當作請求者的惟一IP
        Identify the machine making the request by parsing HTTP_X_FORWARDED_FOR
        if present and number of proxies is > 0. If not use all of
        HTTP_X_FORWARDED_FOR if it is available, if not use REMOTE_ADDR.
        """
        xff = request.META.get('HTTP_X_FORWARDED_FOR')
        remote_addr = request.META.get('REMOTE_ADDR')
        num_proxies = api_settings.NUM_PROXIES

        if num_proxies is not None:
            if num_proxies == 0 or xff is None:
                return remote_addr
            addrs = xff.split(',')
            client_addr = addrs[-min(num_proxies, len(addrs))]
            return client_addr.strip()

        return ''.join(xff.split()) if xff else remote_addr

    def allow_request(self, request, view):
        """
        是否仍然在容許範圍內
        Return `True` if the request should be allowed, `False` otherwise.
        :param request: 
        :param view: 
        :return: True,表示能夠經過;False表示已超過限制,不容許訪問
        """
        # 獲取用戶惟一標識(如:IP)

        # 容許一分鐘訪問10次
        num_request = 10
        time_request = 60

        now = self.ctime()
        ident = self.get_ident(request)
        self.ident = ident
        if ident not in RECORD:
            RECORD[ident] = [now, ]
            return True
        history = RECORD[ident]
        while history and history[-1] <= now - time_request:    #剔除 超時或者是不符合的時間戳。
            history.pop()
        if len(history) < num_request:               #判斷當前IP的訪問的次數(經過時間戳的數量)
            history.insert(0, now)         #把當前的訪問的時間戳放在第一個。
            return True

    def wait(self):
        """
        多少秒後能夠容許繼續訪問
        Optionally, return a recommended number of seconds to wait before
        the next request.
        """
        #last_time = RECORD[self.ident][0] 
        #last_time 就是表明最長時間後才能夠繼續訪問。
        min_time = RECORD[self.ident][-1]   
         #列表中最後一個是最小的時間,當最小的時間失效後就能夠訪問了。
        now = self.ctime()
        return int(60 + min_time - now)   #還有多少秒能夠繼續訪問,就表明着列表中最後一個時間失效剔除後,列表中的個數就少於次數了,這樣不就能夠訪問了嗎?也是能夠訪問的最小時間。


class TestView(APIView):
    throttle_classes = [TestThrottle, ]

    def get(self, request, *args, **kwargs):
        # self.dispatch
        print(request.user)
        print(request.auth)
        return Response('GET請求,響應內容')

    def post(self, request, *args, **kwargs):
        return Response('POST請求,響應內容')

    def put(self, request, *args, **kwargs):
        return Response('PUT請求,響應內容')

    def throttled(self, request, wait):
        """
        訪問次數被限制時,定製錯誤信息
        """

        class Throttled(exceptions.Throttled):
            default_detail = '請求被限制.'
            extra_detail_singular = '請 {wait} 秒以後再重試.'
            extra_detail_plural = '請 {wait} 秒以後再重試.'

        raise Throttled(wait)

views.py                

 

b. 基於用戶IP顯示訪問頻率(利於Django緩存)經常使用的  json

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_RATES': {
        'test_scope': '10/m',
    },
}  

 

在源碼中api

 num, period = rate.split('/')
        num_requests = int(num)
        duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[period[0]]
        return (num_requests, duration)

 

即經過/分割,前面是容許訪問的次數,後面是時間。瀏覽器

即在60s內能夠訪問的次數爲10次緩存

from django.conf.urls import url, include
from web.views import TestView

urlpatterns = [
    url(r'^test/', TestView.as_view()),
]
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response

from rest_framework import exceptions
from rest_framework.throttling import SimpleRateThrottle


class TestThrottle(SimpleRateThrottle):

    # 配置文件定義的顯示頻率的Key
    scope = "test_scope"

    def get_cache_key(self, request, view):
        """
        Should return a unique cache-key which can be used for throttling.
        Must be overridden.

        May return `None` if the request should not be throttled.
        """
        if not request.user:
            ident = self.get_ident(request)
        else:
            ident = request.user

        return self.cache_format % {
            'scope': self.scope,
            'ident': ident
        }


class TestView(APIView):
    throttle_classes = [TestThrottle, ]

    def get(self, request, *args, **kwargs):
        # self.dispatch
        print(request.user)
        print(request.auth)
        return Response('GET請求,響應內容')

    def post(self, request, *args, **kwargs):
        return Response('POST請求,響應內容')

    def put(self, request, *args, **kwargs):
        return Response('PUT請求,響應內容')

    def throttled(self, request, wait):
        """
        訪問次數被限制時,定製錯誤信息
        """

        class Throttled(exceptions.Throttled):
            default_detail = '請求被限制.'
            extra_detail_singular = '請 {wait} 秒以後再重試.'
            extra_detail_plural = '請 {wait} 秒以後再重試.'

        raise Throttled(wait)

views.py

  

 如何實現的訪問頻率控制?

		訪問頻率控制的原理:
			用戶進來時候,把它的訪問時間記錄所有放進來,而後每次再訪問進來時候,把超時或者是不符合的時間戳給剔除。
			而後根據它時間記錄的個數來作判斷。
		
		匿名用戶:沒法控制,由於用戶能夠換代理IP,因此沒發作。
			{
				192.168.1.1:[1521223123.232, 1521223122.232, 1521223121.232],
				192.168.1.2:[1521223123.232, 1521223122.232, 1521223121.232],
				192.168.1.3:[1521223123.232, 1521223122.232, 1521223121.232],
				192.168.1.4:[1521223123.232, 1521223122.232, 1521223121.232],
				192.168.1.5:[1521223123.232, 1521223122.232, 1521223121.232],
				192.168.1.6:[1521223123.232, 1521223122.232, 1521223121.232],
				先剔除時間
			}
		
		真要作匿名用戶的訪問頻率的話,能夠給匿名用戶給隨機的字符串,而後給每次訪問的時候都帶着,用它來記錄時間,可是這樣也不行,由於瀏覽器若是不帶的話,每次都是第一次訪問。憑我如今的能力,尚未辦法能解決,想問您有什麼解決的好辦法呢
		
		登陸用戶:若是有不少帳號,也沒法限制
			{
				alex:[1521223123.232, 1521223122.232, 1521223121.232],
				eric:[1521223123.232, 1521223122.232, 1521223121.232],
			}
		
		參考源碼:from rest_framework.throttling import SimpleRateThrottle
		

  

 

 

SimpleRateThrottle請求頻率源碼分析app

https://blog.csdn.net/u013210620/article/details/79898512 

  

3.版本

a. 基於url的get傳參方式QueryParameterVersioning  

如:/users?version=v1 

REST_FRAMEWORK = {
    'DEFAULT_VERSION': 'v1',            # 默認版本
    'ALLOWED_VERSIONS': ['v1', 'v2'],   # 容許的版本
    'VERSION_PARAM': 'version'          # URL中獲取值的key
}
from django.conf.urls import url, include
from web.views import TestView

urlpatterns = [
    url(r'^test/', TestView.as_view(),name='test'),
]
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.versioning import QueryParameterVersioning


class TestView(APIView):
    versioning_class = QueryParameterVersioning

    def get(self, request, *args, **kwargs):

        # 獲取版本
        print(request.version)
        # 獲取版本管理的類
        print(request.versioning_scheme)

        # 反向生成URL
        reverse_url = request.versioning_scheme.reverse('test', request=request)
        print(reverse_url)

        return Response('GET請求,響應內容')

    def post(self, request, *args, **kwargs):
        return Response('POST請求,響應內容')

    def put(self, request, *args, **kwargs):
        return Response('PUT請求,響應內容')

  

from rest_framework.versioning import URLPathVersioning,QueryParameterVersioning
# URLPathVersioning 是把版本放在url上;最經常使用的
# QueryParameterVersioning  是把版本當作get的參數 ?version

  

基於url的正則方式(URLPathVersioning  

如:/v1/users/  

REST_FRAMEWORK = {
    'DEFAULT_VERSION': 'v1',            # 默認版本
    'ALLOWED_VERSIONS': ['v1', 'v2'],   # 容許的版本
    'VERSION_PARAM': 'version'          # URL中獲取值的key
}
from django.conf.urls import url, include
from web.views import TestView

urlpatterns = [
    url(r'^(?P<version>[v1|v2]+)/test/', TestView.as_view(), name='test'),
]
rom rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.versioning import URLPathVersioning


class TestView(APIView):
    versioning_class = URLPathVersioning

    def get(self, request, *args, **kwargs):
        # 獲取版本
        print(request.version)
        # 獲取版本管理的類
        print(request.versioning_scheme)

        # 反向生成URL
        reverse_url = request.versioning_scheme.reverse('test', request=request)
        print(reverse_url)

        return Response('GET請求,響應內容')

    def post(self, request, *args, **kwargs):
        return Response('POST請求,響應內容')

    def put(self, request, *args, **kwargs):
        return Response('PUT請求,響應內容')  

全局使用

REST_FRAMEWORK = {
    'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.URLPathVersioning",
    'DEFAULT_VERSION': 'v1',
    'ALLOWED_VERSIONS': ['v1', 'v2'],
    'VERSION_PARAM': 'version' 
}

更多的方式參考https://www.cnblogs.com/wupeiqi/articles/7805382.html

4. 解析器(parser) 

#解析器
from rest_framework.parsers import JSONParser
from rest_framework.parsers import FormParser
from rest_framework.parsers import MultiPartParser
from rest_framework.parsers import FileUploadParser

# parser_classes = [JSONParser,FormParser,MultiPartParser]  #解析器,即按照content-type的不一樣來處理數據

#僅處理請求頭content-type爲application/json的請求體爲JSONParser
#僅處理請求頭content-type爲application/x-www-form-urlencoded 的請求體爲FormParser
#僅處理請求頭content-type爲multipart/form-data的請求體爲MultiPartParser  #form表單上傳文件 

同時多個Parser,單個使用的使用就寫須要用的那個

from django.conf.urls import url, include
from web.views import TestView

urlpatterns = [
    url(r'test/', TestView.as_view(), name='test'),
]
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.parsers import JSONParser, FormParser, MultiPartParser


class TestView(APIView):
    parser_classes = [JSONParser, FormParser, MultiPartParser, ]

    def post(self, request, *args, **kwargs):
        print(request.content_type)

        # 獲取請求的值,並使用對應的JSONParser進行處理
        print(request.data)
        # application/x-www-form-urlencoded 或 multipart/form-data時,request.POST中才有值
        print(request.POST)
        print(request.FILES)
        return Response('POST請求,響應內容')

    def put(self, request, *args, **kwargs):
        return Response('PUT請求,響應內容') 

全局使用 

REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES':[
        'rest_framework.parsers.JSONParser'
        'rest_framework.parsers.FormParser'
        'rest_framework.parsers.MultiPartParser'
    ]

} 

注意:個別特殊的值能夠經過Django的request對象 request._request 來進行獲取  

5. 序列化

序列化用於對用戶請求數據進行驗證和數據進行序列化

基於Model自動生成字段

from rest_framework import serializers
from app01.models import *


class CouserSerializers(serializers.ModelSerializer):
	'''
	課程的序列化
	'''
	#自定義的字段

	#source爲表裏面的全部字段
	level = serializers.CharField(source='get_level_display') #自動的幫你添加()
	course_type = serializers.CharField(source='get_course_type_display')

	class Meta:
		model = Course
		fields = ["id",'name',"course_img","course_type","brief","level","period"]
		# depth=2  用深度幫你進行跨表


class CourseDetailViewSerializers(serializers.ModelSerializer):
	'''
	詳細課程的序列化
	'''
	#一對一的反向查詢,fk,choice都是用source,只能取一條或者是一個數據
	name = serializers.CharField(source='course.name')
	img = serializers.CharField(source='course.course_img')
	content = serializers.CharField(source='course.brief')
	id = serializers.CharField(source='course.id')

	#多對多的,用SerializerMethodField(),能夠獲取多個

	#推薦課程
	recommend_courses = serializers.SerializerMethodField()
	#老師
	teachers= serializers.SerializerMethodField()
	# 每一個時間段的價格
	price = serializers.SerializerMethodField()

	# 課程大綱
	course_detail = serializers.SerializerMethodField()

	#課程章節
	coursechapter = serializers.SerializerMethodField()
	#
	# #課時目錄
	# coursesection = serializers.SerializerMethodField()

	# 推薦課程
	def get_recommend_courses(self,obj):  #obj-->  CourseDetail.obj
		# obj.recommendcourse.all()
		return [{"id":item.id,"title":item.name}for item in obj.recommend_courses.all()]

	def get_teachers(self,obj):  #obj-->  CourseDetail.obj
		# obj.recommendcourse.all()
		return [{"id":item.id,"name":item.name,"title":item.title}for item in obj.teachers.all()]
	# 每一個時間段的價格
	def get_price(self,obj):
		return [{"valid_period":item.get_valid_period_display(),"price":item.price}for item in obj.course.price_policy.all()]

	def get_course_detail(self,obj):
		return [{"title":item.title,"content":item.content}for item in obj.courseoutline_set.all()]

	def get_coursechapter(self,obj):
		return [{"chapter":item.chapter,"title":item.name,"summarys":item.summary}for item in obj.course.coursechapters.all()]

	# def get_coursesection(self,obj):
	# 	return [{"chapter":item.chapter,"name":item.name,"summary":item.summary}for item in obj.course.coursechapters.coursesections.all()]

	class Meta:
		model = CourseDetail

		fields = ["id","name","img","hours","teachers","content",'why_study',"what_to_study_brief",
		          "career_improvement","prerequisite","recommend_courses","price",'course_detail','coursechapter',]
class TestView(APIView):
    def get(self, request, *args, **kwargs):

        # 序列化,將數據庫查詢字段序列化爲字典
        data_list = models.UserInfo.objects.all()
        ser = CourseDetailViewSerializers(instance=data_list, many=True)
        # 或
        # obj = models.UserInfo.objects.all().first()
        # ser = CourseDetailViewSerializers(instance=obj, many=False)
        return Response(ser.data)

    def post(self, request, *args, **kwargs):
        # 驗證,對請求發來的數據進行驗證
        print(request.data)
        ser = CourseDetailViewSerializers(data=request.data)
        if ser.is_valid():
            print(ser.validated_data)
        ser.save() #直接保存到數據庫,在這裏會調用GoodSerializer的create方法。
else: print(ser.errors) return Response('POST請求,響應內容')

  

6. 分頁

a根據頁碼進行分頁

from rest_framework.views import APIView
from rest_framework import serializers
from .. import models

from rest_framework.pagination import PageNumberPagination


class StandardResultsSetPagination(PageNumberPagination):
    # 默認每頁顯示的數據條數
    page_size = 1
    # 獲取URL參數中設置的每頁顯示數據條數
    page_size_query_param = 'page_size'

    # 獲取URL參數中傳入的頁碼key
    page_query_param = 'page'

    # 最大支持的每頁顯示的數據條數
    max_page_size = 1


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = "__all__"


class UserViewSet(APIView):
    def get(self, request, *args, **kwargs):
        user_list = models.UserInfo.objects.all().order_by('-id')

        # 實例化分頁對象,獲取數據庫中的分頁數據
        paginator = StandardResultsSetPagination()
        page_user_list = paginator.paginate_queryset(user_list, self.request, view=self)

        # 序列化對象
        serializer = UserSerializer(page_user_list, many=True)

        # 生成分頁和數據
        response = paginator.get_paginated_response(serializer.data)
        return response

  

b位置和個數進行分頁

from rest_framework.views import APIView
from rest_framework import serializers
from .. import models

from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination


class StandardResultsSetPagination(LimitOffsetPagination):
    # 默認每頁顯示的數據條數
    default_limit = 10
    # URL中傳入的顯示數據條數的參數
    limit_query_param = 'limit'
    # URL中傳入的數據位置的參數
    offset_query_param = 'offset'
    # 最大每頁顯得條數
    max_limit = None

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = "__all__"


class UserViewSet(APIView):
    def get(self, request, *args, **kwargs):
        user_list = models.UserInfo.objects.all().order_by('-id')

        # 實例化分頁對象,獲取數據庫中的分頁數據
        paginator = StandardResultsSetPagination()
        page_user_list = paginator.paginate_queryset(user_list, self.request, view=self)

        # 序列化對象
        serializer = UserSerializer(page_user_list, many=True)

        # 生成分頁和數據
        response = paginator.get_paginated_response(serializer.data)
        return response

views.py

  

7. 路由系統

a. 自定義路由

from django.conf.urls import url, include
from web.views import s11_render

urlpatterns = [
    url(r'^test/$', s11_render.TestView.as_view()),
    url(r'^test\.(?P<format>[a-z0-9]+)$', s11_render.TestView.as_view()),
    url(r'^test/(?P<pk>[^/.]+)/$', s11_render.TestView.as_view()),
    url(r'^test/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)$', s11_render.TestView.as_view())
] 

b. 半自動路由

from django.conf.urls import url,include
from django.contrib import admin
from app01 import views

 url(r'^api/(?P<version>\w+)/bookviewset/$', views.BookViewSet.as_view({"get":"list","post":"create"}),name='bookviewset'),
    url(r'^api/bookviewset/$', views.BookViewSet.as_view({"get":"list","post":"create"}),name='bookviewset'),
    # url(r'^bookviewset/(?P<pk>\d+)$', views.BookViewSet.as_view({"get":"retrieve","post":"update"}), name='bookviewsetdetail'), 

c. 全自動路由

from django.conf.urls import url,include
from rest_framework import routers
from app01 import views
router = routers.DefaultRouter()

router.register("bookviewset",views.BookViewSet)

url(r'',include(router.urls)),

    #自動的幫你生成4個url
    #^bookviewset/$ [name='book-list']
    #^bookviewset\.(?P<format>[a-z0-9]+)/?$ [name='book-list']   .json\?format=json
    #^bookviewset/(?P<pk>[^/.]+)/$ [name='book-detail']
    #^bookviewset/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='book-detail']

8. 視圖

根據繼承的類的不一樣有不一樣的形式

                        class View(object):
			
			class APIView(View):
			
			class GenericAPIView(views.APIView):
			
			class GenericViewSet(ViewSetMixin, generics.GenericAPIView)
			# ViewSetMixin 是對as_view裏面的參數進行處理
			
			class ModelViewSet(mixins.CreateModelMixin,
                   mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   GenericViewSet):                    

ViewSetMixin 

url(r'^api/(?P<version>\w+)/bookviewset/$', views.BookViewSet.as_view({"get":"list","post":"create"}),name='bookviewset')  

沒有繼承ViewSetMixin 這個類的話get請求就是執行對應的get的方法。

ModelViewSet把上面的增刪改查都包含了,減小了咱們本身寫麻煩。

from app01.forms import TokenAuth,SVIPPermisson

#解析器
from rest_framework.parsers import JSONParser
from rest_framework.parsers import FormParser
from rest_framework.parsers import MultiPartParser

#版本
from rest_framework.versioning import URLPathVersioning,QueryParameterVersioning
class BookViewSet(viewsets.ModelViewSet):
	authentication_classes=[TokenAuth,]        #認證組件
	# permission_classes = [SVIPPermisson,]   #權限組件
	# throttle_classes = []   #頻率組件
	# parser_classes = [JSONParser,FormParser,MultiPartParser]  #解析器,即按照content-type的不一樣來處理數據
	queryset = Book.objects.all()             # 取的數據
	print(queryset)
	serializer_class = BookModelSerializers   #	序列化器
	pagination_class = MyPageNumberPagination  #分頁器

  

10. 渲染器

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

a. json

訪問URL:

  • http://127.0.0.1:8000/test/?format=json
  • http://127.0.0.1:8000/test.json
  • http://127.0.0.1:8000/test/ 
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers

from rest_framework.renderers import JSONRenderer

from .. import models


class TestSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = "__all__"


class TestView(APIView):
    renderer_classes = [JSONRenderer, ]

    def get(self, request, *args, **kwargs):
        user_list = models.UserInfo.objects.all()
        ser = TestSerializer(instance=user_list, many=True)
        return Response(ser.data) 

b. 表格

訪問URL:

  • http://127.0.0.1:8000/test/?format=admin
  • http://127.0.0.1:8000/test.admin
  • http://127.0.0.1:8000/test/ 
from rest_framework.renderers import AdminRenderer
 renderer_classes = [AdminRenderer, ] 

c. Form表單

訪問URL:

  • http://127.0.0.1:8000/test/?format=form
  • http://127.0.0.1:8000/test.form
  • http://127.0.0.1:8000/test/ 
from rest_framework.renderers import HTMLFormRenderer
renderer_classes = [HTMLFormRenderer, ]

  

等更多渲染器的形式點擊查看  

  

  

完整全面的內容點擊  

  

 

  

 

  

  

 

  

  

  

 

# URLPathVersioning 是把版本放在url上;最經常使用的
# QueryParameterVersioning 是把版本當作get的參數 ?version
相關文章
相關標籤/搜索