zoukankan      html  css  js  c++  java
  • Rest-framework使用

    下载 pip install djangorestframework

    (1) APIView (*****)

      流程:  

         from rest_framework.views import APIView
      APIView(view) 继承了view 在原来基础上扩展功能
      APIView中as_view super了viwe中的as_view
      但是 as_viwe中的dispath 用的是 APIview从写的dispath
      在APIview从写的dispath中从新封装request对象 增加了 权限,认证,频率组件

    (2) 序列化组件(*****)

      from django.core.serializers import serialize # Django的序列化组件
      from rest_framework import serializers DRF的序列化组件
      定义类使用
      class BookSerializer(serializers.Serializer):
        title = serializers.CharField( max_length=32)
        price =serializers.DecimalField(max_digits=5,decimal_places=2)
      在接口类使用
        a = BookSerializer('查询出所有的书籍',many=Ture) many默认False意思是序列化一个
        return Response(a.data)
      post提交数据
      a=CourseSerializer(data=request.data)
      if a.is_valid(): # 校验
        Book.objects.create(**request.data) 不能使用save
        return Response(a.data) # 序列化数据
      else:
        return Response(a.errors) # 序列化错误信息
      一对多字段
        publish_email=serializers.CharField(max_length=32,source="publish.email")
        添加source字段会显示这个里面的值
      多对多字段
        #authors=serializers.CharField(max_length=32,source="authors.all") 是一个QuerySet不使用
        authors=serializers.SerializerMethodField() 使用这个
        def get_authors(self,obj):
          ret=[]
          for i in obj.authors.all():
            ret.append(i.name)
          return ret
      使用 ModelSerializer
      class BookSerializer(serializers.ModelSerializer):
        class Meta:
        model=Book
        # fields=["title","price"]
        fields="__all__"

        # publish=serializers.CharField(max_length=32,source="publish.name")

        # authors=serializers.SerializerMethodField()
        # def get_authors(self,obj):
        # ret=[]
        # for i in obj.authors.all():
        # ret.append({"name":i.name,"pk":i.pk})
        # return ret
      post提交
        def post(self,request):
        serializer=BookSerializer(data=request.data,many=False)

        if serializer.is_valid():
          serializer.save() # create操作 可以使用
          return Response(serializer.data)
        else:
          return Response(serializer.errors)

      如果我查询1条数据()get)的时候 冲突
      所以在写一个视图类 让get put delete放入

      修改一条数据(put)
      def put(self,request,id):
        edit_obj = Book.objects.get(pk=id)
        serializer=BookSerializer(data=request.data,instance=edit_obj)
        if serializer.is_valid():
          serializer.save() # edit_obj.update(request.data)
          return Response(serializer.data)
        else:
          return Response(serializer.errors)

    (3) 视图类(mixin)(*****)

      mixin 混合类

      from rest_framework.mixins import
      ListModelMixin,CreateModelMixin,UpdateModelMixin,DestroyModelMixin,RetrieveModelMixin
      查询                 添加        更新          删除      查询单条
      from rest_framework import generics generics.GenericAPIView使用它调用as_view
      class PublishView(ListModelMixin,CreateModelMixin,generics.GenericAPIView):
        queryset = Publish.objects.all()
        serializer_class = PublishSerializer

        def get(self,request, *args, **kwargs):
          return self.list(request, *args, **kwargs)

        def post(self,request, *args, **kwargs):
          return self.create(request, *args, **kwargs)
      在使用单条查询的时候必须写 PK值
        url(r'^publishes/(?P<pk>d+)/', views.SPublishView.as_view()),
      在类中不用写id
        class SPublishView(UpdateModelMixin,DestroyModelMixin,RetrieveModelMixin,generics.GenericAPIView):

          queryset = Publish.objects.all()
          serializer_class = PublishSerializer

          def get(self,request, *args, **kwargs):
          return self.retrieve(request, *args, **kwargs)

          def put(self, request, *args, **kwargs):
            return self.update(request, *args, **kwargs)

          def delete(self, request, *args, **kwargs):
            return self.destroy(request, *args, **kwargs)


      使用generics.ListCreateAPIView 和 generics.RetrieveUpdateDestroyAPIView 进行封装
        class AuthorsView(generics.ListCreateAPIView):
          queryset = Author.objects.all()
          serializer_class = AuthorSerializer


        class SAuthorsView(generics.RetrieveUpdateDestroyAPIView):
          queryset = Author.objects.all()
          serializer_class = AuthorSerializer


      终极封装 ModelViewSet 必须在url的as_view中写入制定参数
        from rest_framework.viewsets import ModelViewSet

        class AuthorsView(ModelViewSet):
          queryset = Author.objects.all()
          serializer_class = AuthorSerializer

        url(r'^authors/$', views.AuthorsView.as_view({"get":"list","post":"create"})),
        url(r'^authors/(?P<pk>d+)/', views.AuthorsView.as_view({"get":"retrieve","delete":"destroy","put":"update"})),

    (4) 认证组件

      准备2张表
      class User(models.Model):
        user=models.CharField(max_length=32)
        pwd=models.CharField(max_length=32)
        type=((1,"VIP"),(2,"SVIP"),(3,"SSSVIP"))
        user_type=models.IntegerField(choices=type)

      class UserToken(models.Model):
        user=models.OneToOneField("User")
        token=models.CharField(max_length=128)

      在每次登陆时 如果没有就创建 否则就 更新Token值
      import uuid
      random_str = uuid.uuid4()
      if user:
        UserToken.objects.update_or_create(user=user, defaults={"token": random_str})
        response["user"] = user.user
        response["token"] = random_str

      在接口类中使用 authentication_classes = [UserAuth,]
      from rest_framework.authentication import BaseAuthentication
      from rest_framework.exceptions import AuthenticationFailed
      class UserAuth(BaseAuthentication):
        def authenticate(self,request):
          token=request.query_params.get("token")
          usertoken=UserToken.objects.filter(token=token).first()
          if usertoken:
            return usertoken.user,usertoken.token
          else:
            raise AuthenticationFailed("认证失败!")

     

    (5) 权限组件

      判断等级进行判断
      在接口类中使用 permission_classes = [SVIPPermission]

      from rest_framework.permissions import AllowAny
      from rest_framework.permissions import BasePermission
      class SVIPPermission(BasePermission):
        message="您没有访问权限!"
        def has_permission(self,request,view):
        if request.user.user_type >= 2: #判断
          return True
        return False

     

    (6) 频率组件

      在接口类中使用 throttle_classes = [VisitThrottle]
      from rest_framework.throttling import BaseThrottle
      class VisitThrottle(BaseThrottle):
        def allow_request(self,request,view):
        """
        限制IP每分钟访问不能超过3次
        :param request:
        :param view:
        :return:
        """
        print(self.get_ident(request)) #拿到IP
        remote_addr = request.META.get('REMOTE_ADDR') #拿到IP
        print("REMOTE_ADDR",remote_addr)
        return False

      可以使用自带的频率控制类
      from rest_framework.throttling import SimpleRateThrottle
      class VisitThrottle(SimpleRateThrottle):
        scope="visit_rate"
        def get_cache_key(self,request, view):
          return self.get_ident(request)

      需要在settings中设置
      REST_FRAMEWORK={
        "DEFAULT_THROTTLE_CLASSES": ("app01.utils.throttle_class.VisitThrottle",),
        "DEFAULT_THROTTLE_RATES": {
          "visit_rate": "10/m",
        },
      }

     

    (7) 分页组件

      from rest_framework.pagination import PageNumberPagination

      class MyPageNumberPagination(PageNumberPagination):
        page_size=2 #每页显示多少条
        page_query_param="page_num" # get取到的页面名称 &page_num=1
        page_size_query_param="size" # 临时调整 &size = 3 每页显示3条
        max_page_size=5 # 最大可以临时调整5条

      print(request.user,request.auth)

      book_list=Book.objects.all() # 对所有书分页

      pnp=MyPageNumberPagination() # 分页器对象

      paged_book_list=pnp.paginate_queryset(book_list,request) # 对什么分页

      serializer=BookSerializer(paged_book_list,many=True) # 序列化分页后的数据

     

    (8) 解析器组件(*****)

      from rest_framework.parsers import JSONParser,FormParser,FileUploadParser
      在类中设置 parser_classes = [] 自定义格式
      根据客户端发送到后端的数据 是用的json格式还是urlencoded格式
      根据格式服务器根据那种格式解
      发送的请求体格式 a=1&b=2 urlencoded格式 在form表单中entype中设置格式 或
      ajax也是可以用contenttype设置
      发送到服务器我根据什么解格式

     

    (9) 响应器组件

      默认支持2种响应
      当浏览器去访问时候返给你一个页面
      用postman发给的是json数据

     

    (10) url注册器

      from rest_framework import routers
      router = routers.DefaultRouter()
      router.register("authors",views.AuthorsView) #根据名字 和视图类就可以访问

      放到url中 from django.conf.urls import url,include
      url(r'^', include(router.urls)),

     

  • 相关阅读:
    Java8基础学习之Object类
    Java8基础之equals方法和==的区别
    Spring集成ElasticSearch
    ElasticSearch常用的查询过滤语句
    数据库查看SQL执行计划
    数据库优化总结
    ElasticSearch之集群原理
    curl命令操作ElasticSearch总结
    ElasticSearch相关概念总结
    ElasticSearch基础入门
  • 原文地址:https://www.cnblogs.com/luchenhui/p/10453505.html
Copyright © 2011-2022 走看看