• HTTP请求方式


    HTTP协议中请求的8中方法

    • OPTIONS获取服务器支持的HTTP请求方法;
    • HEAD跟get很像,但是不返回响应体信息,用于检查对象是否存在,并获取包含在响应消息头中的信息。
    • GET向特定的资源发出请求,得到资源。
    • POST向指定资源提交数据进行处理的请求,用于添加新的内容。
    • PUT向指定资源位置上传其最新的内容,用于修改某个内容。
    • DELETE请求服务器删除请求的URI所标识的资源,用于删除。
    • TRACE回馈服务器收到的请求,用于远程诊断服务器。
    • CONNECT用于代理进行传输,如使用ssl


    其中GET、POST最为常见

    GET:用于请求服务器上的数据,理解为读取就好了。DRF中generics.ListAPIView源码如下:

    class ListAPIView(mixins.ListModelMixin,
                      GenericAPIView):
        """
        Concrete view for listing a queryset.
        """
        def get(self, request, *args, **kwargs):
            return self.list(request, *args, **kwargs)
    

      

    class ListModelMixin(object):
        """
        List a queryset.
        """
        def list(self, request, *args, **kwargs):
            queryset = self.filter_queryset(self.get_queryset())
     
            page = self.paginate_queryset(queryset)
            if page is not None:
                serializer = self.get_serializer(page, many=True)
                return self.get_paginated_response(serializer.data)
     
            serializer = self.get_serializer(queryset, many=True)
            return Response(serializer.data)

    说明PUT/POST/PATCH方法前先引入一个概念,幂等,来帮助我们更好地理解这几种方法的区别。

    幂等idempotent :如果一个方法重复执行多次,产生的效果是一样的,那就是幂等的。幂等的意思是如果相同的操作再执行第二遍第三遍,结果还是一样。
    关于POST/PUT/PATCH/的区别

    POST:用来创建一个子资源

    如 /api/users,会在users下面创建一个user,如users/1;POST方法不是幂等的,多次执行,将导致多条相同的条目被创建。(比如在提交表单时刷新,会POST多个相同的表单给服务器)。重点:POST不是幂等的。

    PUT:比较正确的定义是Create or Update
    例如 PUT /items/1 的意思是替换 /items/1 ,存在则替换,不存在则创建。
    所以,PUT方法一般会用来更新一个已知资源。

    PATCH:是对PUT方法的补充,用来对已知资源进行局部更新,PATCH是幂等的。

    POST /api/articles
    PUT /gists/:id/stars
    如果产生两个资源,就说明这个服务不是idempotent(幂等的),因为多次使用产生了副作用;如果后一个请求把第一个请求覆盖掉了,那这个服务就是idempotent的。
    前一种情况,应该使用POST方法;
    后一种情况,应该使用PUT方法。
    搞清楚这个概念我们再来看看源码。

    POST:向服务器提交数据,常见的提交表单都是POST方法。DRF中generics.ListAPIView源码如下:

    class CreateAPIView(mixins.CreateModelMixin,
                        GenericAPIView):
     
        """
        Concrete view for creating a model instance.
        """
        def post(self, request, *args, **kwargs):
            return self.create(request, *args, **kwargs)
    

      

    class CreateModelMixin(object):
        """
        Create a model instance.
        """
        def create(self, request, *args, **kwargs):
            serializer = self.get_serializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            self.perform_create(serializer)
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
     
        def perform_create(self, serializer):
            serializer.save()
     
        def get_success_headers(self, data):
            try:
                return {'Location': data[api_settings.URL_FIELD_NAME]}
            except (TypeError, KeyError):
                return {}
    

      PUT/PATCH:

    class UpdateAPIView(mixins.UpdateModelMixin,
                        GenericAPIView):
     
        """
        Concrete view for updating a model instance.
        """
     
        def put(self, request, *args, **kwargs):
            return self.update(request, *args, **kwargs)
     
        def patch(self, request, *args, **kwargs):
            return self.partial_update(request, *args, **kwargs)
    

      

    class UpdateModelMixin(object):
        """
        Update a model instance.
        """
        def update(self, request, *args, **kwargs):
            partial = kwargs.pop('partial', False)
            instance = self.get_object()
            serializer = self.get_serializer(instance, data=request.data, partial=partial)
            serializer.is_valid(raise_exception=True)
            self.perform_update(serializer)
            return Response(serializer.data)
    

      

    DELETE:删除服务器上的某个资源。DRF中源码如下:

    class DestroyAPIView(mixins.DestroyModelMixin,
                         GenericAPIView):
     
        """
        Concrete view for deleting a model instance.
        """
        def delete(self, request, *args, **kwargs):
            return self.destroy(request, *args, **kwargs)
    

      

    class DestroyModelMixin(object):
        """
        Destroy a model instance.
        """
        def destroy(self, request, *args, **kwargs):
            instance = self.get_object()
            self.perform_destroy(instance)
            return Response(status=status.HTTP_204_NO_CONTENT)
     
        def perform_destroy(self, instance):
            instance.delete()

    这段代码就完全可以对应CRUD,DRF还是封装的很好的

    class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin,
                                       mixins.UpdateModelMixin,
                                       mixins.DestroyModelMixin,
                                       GenericAPIView):
        """
        Concrete view for retrieving, updating or deleting a model instance.
        """
        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 patch(self, request, *args, **kwargs):
            return self.partial_update(request, *args, **kwargs)
     
        def delete(self, request, *args, **kwargs):
            return self.destroy(request, *args, **kwargs)
    

      


    最后是OPTIONS和HEAD

    HEAD:只请求页面的首部

    OPTIONS:它用于获取当前URL所支持的方法。如果请求成功,会有一个Allow的头包含类似“GET,POST”这样的信息

  • 相关阅读:
    java logging 配置文件
    oracle exception使用
    java keytool 用法
    【转】ant学习笔记之(ant执行命令的详细参数和Ant自带的系统属性)
    [转]Ivy入门学习
    关于java.nio.Buffer的API
    如何查看LINUX操作系统是多少位的
    Linux cpio命令的使用
    window.open()使用参考
    【原创】个人站点建设(待续)
  • 原文地址:https://www.cnblogs.com/yoyo1216/p/10678307.html
Copyright © 2020-2023  润新知