zoukankan      html  css  js  c++  java
  • django rest framework组件下的详细功能的实现

    Django Rest Framework框架组件的执行流程

    rest framework组件为我们提供了下面的这些功能:
    按照HTTP请求的生命周期去记; 先是进入路由,在视图,进入dispatch()里面,然
    后提供的是版本,权限,认证,频率,然后从 解析器()里面取数据,再序列化,分页,渲染器。
    

    1.认证和授权

    a. 用户url传入的token认证(作为url的参数传入)

    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
    

    认证和权限

    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里面去配置全局信息。

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

    2.用户访问次数/频率限制

    a. 基于用户IP限制访问频率

    这种方法是无法控制的,因为用户可以换代理IP,所以没有完全的限制。

    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缓存)常用的  

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

     

    在源码中

     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请求频率源码分析

    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
  • 相关阅读:
    Java8 Stream Function
    PLINQ (C#/.Net 4.5.1) vs Stream (JDK/Java 8) Performance
    罗素 尊重 《事实》
    小品 《研发的一天》
    Java8 λ表达式 stream group by max then Option then PlainObject
    这人好像一条狗啊。什么是共识?
    TOGAF TheOpenGroup引领开发厂商中立的开放技术标准和认证
    OpenMP vs. MPI
    BPMN2 online draw tools 在线作图工具
    DecisionCamp 2019, Decision Manager, AI, and the Future
  • 原文地址:https://www.cnblogs.com/zenghui-python/p/11731669.html
Copyright © 2011-2022 走看看