zoukankan      html  css  js  c++  java
  • python全栈开发day102-django rest-framework框架

    1.频次访问组件

      1) 手写版本  

    # class VisitThrottle(BaseThrottle):
    #
    #     def __init__(self):
    #         self.history = None
    #
    #     def allow_request(self, request, view):
    #         """
    #         限制IP每分钟访问不能超过3次
    #         :param request:
    #         :param view:
    #         :return:
    #         """
    #
    #         # 确定访问IP
    #         print(self.get_ident(request))
    #         remote_addr = request.META.get('REMOTE_ADDR')
    #         print("REMOTE_ADDR", remote_addr)
    #
    #         # 获取当次访问时间
    #         ctime = time.time()
    #
    #         # if 第一次访问
    #         if remote_addr not in VISIT_RECORD:
    #             VISIT_RECORD[remote_addr] = [ctime, ]
    #             return True
    #
    #         history = VISIT_RECORD.get(remote_addr)
    #         self.history = history
    #
    #         while history and ctime - history[-1] > 60:
    #             history.pop()
    #
    #         if len(history) < 3:
    #             history.insert(0, ctime)
    #             return True
    #         else:
    #             return False
    #
    #     def wait(self):
    #         # 当前访问时间
    #         ctime = time.time()
    #
    #         #  访问时间历史记录 self.history
    #
    #         return 60 - (ctime - self.history[-1])
    频率访问组件

      2)rest-framework自带的简单组件

    from rest_framework.throttling import SimpleRateThrottle
    
    
    class VisitedThrottle(SimpleRateThrottle):
        scope = 'visited_rate'
        THROTTLE_RATES = {'visited_rate': '3/m'}
    
        def get_cache_key(self, request, view):
            return self.get_ident(request)
    
    # 写在全局
    settings.py
        "DEFAULT_THROTTLE_CLASSES": ("app01.utils.throttle_class.VisitThrottle",),
        "DEFAULT_THROTTLE_RATES": {
            "visit_rate": "10/m",
        },
    simpleRateThrottle

    2.URL解析器

    用法:

    产生4条url:

    支持.json等格式访问:

    3.分页

    # 定义分页组件类
    class MyPageNumberPagination(PageNumberPagination):
        page_size = 2
        page_query_param = 'p'
        page_size_query_param = 'size'
        max_page_size = 3
    
    
    class BookView(APIView):
        # parser_classes = [FormParser, JSONParser, MultiPartParser]
    
        def get(self, request):
            book_list = Book.objects.all().order_by('pk')
            mypagination = MyPageNumberPagination() # 分页
            pagination_list = mypagination.paginate_queryset(book_list, request) # 分页
            bs = BookSerializer(pagination_list, many=True)
            return response.Response(bs.data)
    
    
    class PublishView(ModelViewSet):
        authentication_classes = [UserAuth, ]
        # throttle_classes = [UserThrottle, ]
    
        permission_classes = [UserPermission, ] 
        queryset = Publish.objects.all().order_by('pk') #分页
        serializer_class = PublishSerializer
        pagination_class = MyPageNumberPagination  # 分页
    

      

    4.响应器

    REST_FRAMEWORK={
    
        'DEFAULT_PARSER_CLASSES': (
            'rest_framework.parsers.JSONParser',
            'rest_framework.parsers.FormParser',
        ),
    
       'DEFAULT_AUTHENTICATION_CLASSES': (
            'app01.utils.auth_class.UserAuth',
    
        ),
    
        'DEFAULT_PERMISSION_CLASSES': (
             'app01.utils.permission_class.SVIPPermission',
        ),
    
        "DEFAULT_THROTTLE_CLASSES": ("app01.utils.throttle_class.VisitThrottle",),
        "DEFAULT_THROTTLE_RATES": {
            "visit_rate": "10/m",
        },
    
        'DEFAULT_RENDERER_CLASSES': (
            'rest_framework.renderers.JSONRenderer',
            #'rest_framework.renderers.BrowsableAPIRenderer',
        ),
        # "PAGE_SIZE":3
    }

     5. 重写serialiazer中的create方法,解决配置列的报错问题read_only或write_only

      

    class BookSerializer(serializers.ModelSerializer):
    
    
        publish_name=serializers.CharField(max_length=32,source="publish.name",read_only=True)
        # publish_pk=serializers.CharField(max_length=32,source="publish.pk",read_only=True)
        # 该字段get的时候显示,post的时候不会写入create方法
        publish_info=serializers.SerializerMethodField(read_only=True)
        authors_list=serializers.SerializerMethodField(read_only=True)
        def get_authors_list(self,obj):
            ret=[]
            for i in obj.authors.all():
                ret.append({"name":i.name,"pk":i.pk})
            return ret
    
        def get_publish_info(self,obj):
    
            return {"name":obj.publish.name,"publish_pk":obj.publish.pk}
    
    
        def create(self, validated_data):pass
    
        class Meta:
            model = Book
            # fields=["title","price"]
            fields = "__all__"
            # 设置字段get的时候不显示,post的时候会写入create方法
            extra_kwargs={"publish":{"write_only":True},"authors":{"write_only":True}}

     重写write:

    BookSerializer

    class BookSerializer(serializers.ModelSerializer):
        publish_info = serializers.SerializerMethodField(read_only=False)
        authors_info = serializers.SerializerMethodField(read_only=False)
    
        def get_authors_info(self, obj):
            temp = []
            for i in obj.authors.all():
                temp.append({
                    "author_pk": i.pk,
                    "author_name": i.name,
                    "author_email": i.email
                })
            return temp
    
        def get_publish_info(self, obj):
            return {"publish_pk": obj.publish.pk,
                    "publish_name": obj.publish.name,
                    "publish_addr": obj.publish.address}
    
        class Meta:
            model = Book
            fields = "__all__"
            # exclude = ["publish"]
            extra_kwargs = {
                "publish": {"read_only": True},
                "authors": {"read_only": True}
            }
    
        def create(self, validated_data):
            my_validated_data = validated_data['owner']
    
            authors_info = my_validated_data.pop('authors_info')
            publish_info = my_validated_data.pop('publish_info')
            my_validated_data['publish_id'] = publish_info.get('publish_pk')
            authors_pk_list = []
            for i in authors_info:
                authors_pk_list.append(i.get('author_pk'))
            self.instance = Book.objects.create(**my_validated_data)
            self.instance.authors.set(authors_pk_list)
            return self.instance
    类BookSerializer

    BookView /重点.要将非model中的字段通过save(owner=request.data传给validated_data)

    class BookView(APIView):
        # parser_classes = [FormParser, JSONParser, MultiPartParser]
    
        def get(self, request):
            book_list = Book.objects.all().order_by('pk')
            mypagination = MyPageNumberPagination()
            pagination_list = mypagination.paginate_queryset(book_list, request)
            bs = BookSerializer(pagination_list, many=True)
            return response.Response(bs.data)
    
        def post(self, request):
            serializer = BookSerializer(data=request.data)
    
            if serializer.is_valid():
    
                serializer.save(owner=request.data)
                # print(serializer.data)  # 必须在save()方法之后
                # {'id': 8, 'title': '第10本书', 'price': 12, 'publish': 1, 'authors': [1, 3]}
                print(serializer.validated_data)
                # OrderedDict([('title', '第10本书'), ('price', 12), ('publish', < Publish: 沙河出版社 >),
                # ('authors', [ < Author: 下马哥 >, < Author: eva >])])
                return response.Response(serializer.data)
            else:
                return response.Response(serializer.errors)
    类BookView

    https://www.cnblogs.com/yuanchenqi/articles/8719520.html

  • 相关阅读:
    Python 分页功能
    Django 项目CRM总结
    Django 如何实现文件下载
    Python连接redis方法
    Python 微信公众号发送消息
    Python 邮件发送消息
    python 函数内置方法short_desc
    Django 定制验证码
    Django Ajax学习二之文件上传
    Django Ajax学习二之csrf跨站请求伪造
  • 原文地址:https://www.cnblogs.com/wuchenggong/p/9687107.html
Copyright © 2011-2022 走看看