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

posted @ 2018-09-21 16:15  富0代  阅读(160)  评论(0编辑  收藏  举报
返回
顶部