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", },
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
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)
https://www.cnblogs.com/yuanchenqi/articles/8719520.html