DjangoRESTframework详细用法

DRF

序列化定义

什么叫做序列化

  • 将程序中的一个数据结构类型转换为其它格式(字典、JSON、XML等)

什么叫做反序列化

  • 将其它格式转换为程序中的数据

在开发REST API时,视图中要频繁的进行序列化与反序列化的编写

REST API的视图

在视图中需要做的核心

  • 1、将数据库数据序列化为前端所需要的格式,并返回;
  • 2、将前端发送的数据反序列化为模型类对象,并保存打数据库中。

虽然每个视图具体的操作不同,但CRUD的实现流程基本套路化,这部分代码是可以复用简化的

CRUD的实现流程

  • 增:

    • 检验请求数据->执行反序列化过程->保存到数据库->将保存的对象序列化并返回
  • 删:

    • 判断要删除的数据是否存在->执行数据库删除
  • 改:

    • 判断要修改的数据是否存在->检验请求的数据->执行反序列化过程->保存数据库->将保存的对象序列化并返回
  • 查:

    • 查询数据库->将数据序列化并返回

Django REST framework

它是一个用户构建Web API的强大而灵活的工具,通常简称为DRF框架或REST framework

特点:

  • 1、提供了定义序列化器Serializer的方法,可以快速根据Django ORM或者其它库自动序列化/反序列化
  • 2、提供了丰富的类视图、Mixin扩展类,简化视图的编写
  • 3、丰富的定制层级:函数视图、类视图、视图集合到自动生成API,满足各种需要
  • 4、多种身份认证和权限认证方式的支持
  • 5、内置了限流系统
  • 6、直观的API web界面
  • 7、可扩展性,插件丰富

DRF的使用

DRF是以Django扩展应用的方式提供的,所以我们可以直接利用已有的Django环境而无需重新创建

安装DRF

  • pip install djangorestframework

添加rest_framework应用

  • 在settings.py中的INSTALLED_APPS中添加"rest_framework"

序列化

定义方法

  • DRF中的Serializer使用类定义,需要继承自rest_framework.serializers.Serializer

  • 定义序列化器的字段与选项‘

    • 常用字段1[外链图片转存失败(img-41GliTfd-1564366801227)(assets/99d3c9a5e0987decdf0a750e36a03218c788cbe820b6f9a7a5d5e80a9b73a97f.png)]
    • 常用字段2[外链图片转存失败(img-7blNVeKY-1564366801229)(assets/73b09276e0593d68719dee9e866bb2e09b7f12967d4684730252d97fe327e1d8.png)]
    • 选项参数
    • 通用参数[外链图片转存失败(img-d5lTVQFt-1564366801229)(assets/44d9eb0856a379154fe4ec4b0b03a5ce65af73936b0cecb7e3afcf6b81af4991.png)]
  • serializer不是只能为数据库模型类定义,也可以为非数据库模型类的数据定义。serializer是独立于数据库之外的存在。

使用

  • 定义序列化器

  • 创建序列化器对象

    • 序列化器和模型类的属性要保持一致

    • 构造方法

      • Serializer(instance=None,data=empty,**kwargs)

      • 1、用于序列化时,将模型类对象传入instance参数

      • 2、用于反序列化时,将要被反序列化的数据传入data参数

      • 3、除了instance和data参数外,在构造Serializer对象时,还可通过context参数额外添加数据

        通过context参数附加的数据,可以通过Serializer对象的context属性获取

  • 基本使用

    • 创建要查询的实例化对象

    • 构造序列化器对象

      如果要被序列化的是包含多条数据的查询集QuerySet,可以通过添加many=True参数补充说明

    • 获取序列化数据

      • 通过序列化器对象.data可以获取序列化后的数据
  • 关系对象嵌套序列化

    • 如果需要序列化的数据中包含有其他关联对象,则对关联对象数据的序列化需要指明。

    • 对于关联字段

      • PrimaryKeyRelatedField

        • 此字段将被序列化为关联对象的主键。
        • 指明字段时需要包含read_only=True或者queryset参数:
        • 包含read_only=True参数时,该字段将不能用作反序列化使用
      • StringRelatedField

        • 此字段将被序列化为关联对象的字符串表示方式(即__str__方法的返回值)
      • 使用关联对象的序列化器

    • many参数

      • 如果关联的对象数据不是只有一个,而是包含多个数据,需要补充many=True参数

反序列化

验证

  • 使用序列化器进行反序列化时,需要对数据进行验证后,才能获取验证成功的数据或保存成模型类对象

  • 在获取反序列化的数据前,必须调用is_valid()方法进行验证,验证成功返回True,否则返回False

    • True

      • 可以通过序列化器的validated_data属性获取数据
    • False

      • 可以通过序列化器对象的errors属性获取错误信息,返回字典,包含了字典和字段的错。
      • 如果是非字段错误,可以通过修改REST framework配置中的NON_FIELD_ERRORS_KEY来控制错误字典中的键名
    • is_valid()还可以在验证失败时抛出异常serializers.ValidationError,可以通过传递raise_exception=True参数开启,REST framework接收到此异常,会向前端返回HTTP 400 Bad Request响应

验证的补充

  • 在定义序列化器时,指明每个字段的序列化类型和选项参数,本身就是一种验证行为

  • validate_<field_name>

    • 对<field_name>字段进行验证
  • validate

    • 在序列化器中需要同时对多个字段进行比较验证时,可以定义validate来验证
  • validators

    • 在字段中添加validators选项参数,也可以补充验证行为,使用[]包裹验证的函数

      • 验证的函数一定要在定义序列化器之前

保存

  • create()
  • update()
  • 如果创建序列化器对象的时候没有传递instance实例,则调用save()方法的时候,create()被调用
  • 如果传递了instance实例,则调用save()方法的时候,update()被调用
  • 在对序列化器进行save()保存时,可以额外传递数据,这些数据可以在create()和update()中的validated_data参数获取到

模型类序列化器

和常规的Serializer相同,但有部分扩展:

  • 基于模型类自动生成一系列字段
  • 基于模型类自动为Serializer生成validators
  • 包含默认的create()和update()的实现

定义

  • 语法格式

    class 序列化器类(serializers.ModelSerializer)
    class Meta:
    model = 指明参照哪个模型类
    fields = 指明为模型类的哪些字段生成

  • 可以在shell中查看自动生成的BookInfoSerializer的具体实现

  • 指定字段

    • fields

      • __all__表名包含所有字段
    • exclude

      • 可以明确排除掉哪些字段
    • 显示指明字段

      • 使用fields = (‘要显示的字段名’)
    • 指明只读字段

      • read_only_fields,指明只读字段,仅用于序列化输出的字段
  • 添加额外参数

    • extra_kwargs

      class 序列化器类名(serializer.ModelSerializer)
      class Meta:
      model = 指明模型类
      fileds= 指明哪些字段
      extra_kwargs = {
      “参数”:{},
      “参数”:{},
      }

视图

Request

  • DRF传入视图的request对象不再是Django默认的HttpRequest对象,而是DRF提供的扩展类的Request类的对象

  • DRF提供了Parser解析器,在接收请求后会自动根据Content-Type指明的请求数据类型将请求数据进行parser解析,解析为类字典对象保存到Request对象中

  • Request对象的数据是自动根据前端发送数据的格式进行解析之后的结果

  • 常用属性

    • .data

      • 返回解析之后的请求体数据
      • 包含了解析之后的文件和非文件数据
      • 包含了对POST/PUT/PATCH请求方式解析后的数据
      • 利用了REST framework的parsers解析器,不仅支持表单类型数据,也支持JSON数据
    • .query_params

      • 与标准的request.GET()相同,只不过是改了名字

Response

  • 构造方式

    • Response(data,status=None,template_name=None,headers=None,content_type=None)

    • data

      • data数据不要是render处理之后的数据,只需传递python的内建类型即可,DRF会使用render渲染器处理data
      • data不能是复杂结构的数据,如Django的模型类对象,对于这样的数据可以使用Serizlizer序列化器序列化处理后再传递给data参数
    • 参数说明

      • data

        • 为响应准备的序列化处理后的数据
      • status

        • 状态码,默认200
      • template_name

        • 模板名称,如果使用HTMLRender时需指明
      • headers

        • 用于存放响应头信息的字典
      • content_type

        • 响应数据的Content-Type,通常此参数无需传递,DRF会根据前端所需类型数据来设置该参数
  • 状态码

    • 1xx 信息告知

      HTTP_100_CONTINUE
      HTTP_101_SWITCHING_PROTOCOLS

    • 2xx 成功

      HTTP_200_OK
      HTTP_201_CREATED
      HTTP_202_ACCEPTED
      HTTP_203_NON_AUTHORITATIVE_INFORMATION
      HTTP_204_NO_CONTENT
      HTTP_205_RESET_CONTENT
      HTTP_206_PARTIAL_CONTENT
      HTTP_207_MULTI_STATUS

    • 3xx 重定向

      HTTP_300_MULTIPLE_CHOICES
      HTTP_301_MOVED_PERMANENTLY
      HTTP_302_FOUND
      HTTP_303_SEE_OTHER
      HTTP_304_NOT_MODIFIED
      HTTP_305_USE_PROXY
      HTTP_306_RESERVED
      HTTP_307_TEMPORARY_REDIRECT

    • 4xx 客户端错误

      HTTP_400_BAD_REQUEST
      HTTP_401_UNAUTHORIZED
      HTTP_402_PAYMENT_REQUIRED
      HTTP_403_FORBIDDEN
      HTTP_404_NOT_FOUND
      HTTP_405_METHOD_NOT_ALLOWED
      HTTP_406_NOT_ACCEPTABLE
      HTTP_407_PROXY_AUTHENTICATION_REQUIRED
      HTTP_408_REQUEST_TIMEOUT
      HTTP_409_CONFLICT
      HTTP_410_GONE
      HTTP_411_LENGTH_REQUIRED
      HTTP_412_PRECONDITION_FAILED
      HTTP_413_REQUEST_ENTITY_TOO_LARGE
      HTTP_414_REQUEST_URI_TOO_LONG
      HTTP_415_UNSUPPORTED_MEDIA_TYPE
      HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE
      HTTP_417_EXPECTATION_FAILED
      HTTP_422_UNPROCESSABLE_ENTITY
      HTTP_423_LOCKED
      HTTP_424_FAILED_DEPENDENCY
      HTTP_428_PRECONDITION_REQUIRED
      HTTP_429_TOO_MANY_REQUESTS
      HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE
      HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS

    • 5xx 服务器错误

      HTTP_500_INTERNAL_SERVER_ERROR
      HTTP_501_NOT_IMPLEMENTED
      HTTP_502_BAD_GATEWAY
      HTTP_503_SERVICE_UNAVAILABLE
      HTTP_504_GATEWAY_TIMEOUT
      HTTP_505_HTTP_VERSION_NOT_SUPPORTED
      HTTP_507_INSUFFICIENT_STORAGE
      HTTP_511_NETWORK_AUTHENTICATION_REQUIRED

视图说明

  • 两个基类

    • APIView

      • 定义:APIView是RESTframework提供的所有视图的基类,继承自Django的View父类

      • 与View的不同之处

        • 传入到视图方法中的是DRF的Request对象,而不是Django的HttpRequest对象
        • 视图方法可以返回DRF的Response对象,视图会为响应数据设置(render)符合前端要求的格式
        • 任何APIException异常都会被捕获到,并且处理成合适的响应信息
        • 在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制
      • 支持定义的属性

        • authentication_classes 列表或元组,身份认证类
        • permissoin_classes 列表或元组,权限检查类
        • throttle_classes 列表或元组,流量控制类
      • 在APIView中仍以常规的类视图定义方法来实现get()、post()或者其他请求方式的方法

    • GenericAPIView

      rest_framework.generics.GenericAPIView

      • 1、继承自APIView,增加了对列表视图和详情视图可能用到的通用支持方法,通常使用时可以搭配一个或多个Mixin扩展类

      • 2、支持定义的属性

        • 列表视图与详情视图通用

          • queryset 列表视图的查询集
          • serializer_class 视图使用的序列化器
        • 列表视图使用

          • pagination_class 分页控制类
          • filter_backends 过滤控制后端
        • 详情页视图使用

          • lookup_field 查询单一数据库对象时使用的条件字段,默认为“pk”
          • lookup_url_kwarg 查询单一数据时URL中的参数关键字名称,默认与look_field相同
      • 3、提供的方法

        • 列表视图与详情视图通用

          • get_queryset(self)

            • 返回视图使用的查询集,是列表视图与详情视图获取数据的基础,默认 返回queryset属性,可以重写
          • get_serializer_class(self)

            • 返回序列化器类,默认返回serializer_class,可以重写
          • get_serializer(self,*args,**kwargs)

            • 返回序列化器对象,被其他视图或扩展类使用,如果我们在视图中想要获取序列化器对象,可以直接调用此方法
          • 注意,在提供序列化器对象的时候,REST framework会向对象的context属性补充三个数据:request、format、view,这三个数据对象可以在定义序列化器时使用。

        • 详情视图使用

          • get_object(self)

            • 返回详情视图所需的模型类数据对象,默认使用lookup_field参数来过滤queryset。在视图中可以调用该方法获取详情信息的模型类对象
            • 如果详情访问的模型类对象不存在,会返回404
            • 该方法会默认使用APIView提供的check_object_permissions方法检查当前对象是否有权被访问
      • 4、五个扩展类和子类视图

        • ListModelMixin

          源代码:
          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)

          • 列表视图扩展类,提供list(request,*args,**kwargs)方法快速实现列表视图,返回200状态码
          • list方法会对数据进行过滤和分页
        • CreateModelMixin

          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': str(data[api_settings.URL_FIELD_NAME])}
              except (TypeError, KeyError):
                  return {}
          
          • 创建视图扩展类,提供create(request,*args,**kwargs)方法快速实现创建资源的视图,成功返回201状态码
          • 如果序列化器对前端发送的数据验证失败,返回400错误
        • RetrieveModelMixin

          class RetrieveModelMixin(object):
          “”"
          Retrieve a model instance.
          “”"
          def retrieve(self, request, *args, **kwargs):
          # 获取对象,会检查对象的权限
          instance = self.get_object()
          # 序列化
          serializer = self.get_serializer(instance)
          return Response(serializer.data)

          • 详情视图扩展类,提供retrieve(request,*args,**kwargs)方法,可以快速实现返回一个存在的数据对象。
          • 如果存在,返回200,否则返回404
        • UpdateModelMixin

          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)

              if getattr(instance, '_prefetched_objects_cache', None):
                  # If 'prefetch_related' has been applied to a queryset, we need to
                  # forcibly invalidate the prefetch cache on the instance.
                  instance._prefetched_objects_cache = {}
          
              return Response(serializer.data)
          
          def perform_update(self, serializer):
              serializer.save()
          
          def partial_update(self, request, *args, **kwargs):
              kwargs['partial'] = True
              return self.update(request, *args, **kwargs)
          
          • 更新视图扩展类,提供update(request,*args,**kwargs)方法,可以快速实现更新一个存在的数据对象,也提供partial_update(request,*args,**kwargs)方法,可以实现局部刷新
          • 成功返回200,失败返回400
        • DestroyModelMixin

          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()
          
          • 删除视图扩展类,提供destroy(request,*args,**kwargs)方法,可以快速实现删除一个存在的数据对象
          • 成功返回204,不存在返回404
        • 子类视图

          • ListAPIView

            • get
          • CreateAPIView

            • post
          • RetireveAPIView

            • get
          • UpdateAPIView

            • put
            • patch
          • DestroyAPIView

            • delete
          • 集成的子类视图

            • RetireveUpdateAPIView

              • get
              • put
              • patch
            • RetrieveUpdateDestoryAPIView

              • get
              • put
              • patch
              • delete

视图集ViewSet

  • 使用视图集ViewSet,可以将一系列逻辑相关的动作放到一个类中:

    • list()

      • 提供一组数据
    • retrieve()

      • 提供单个数据
    • create()

      • 创建数据
    • update()

      • 更新数据
    • destory()

      • 删除数据
  • ViewSet视图集类不再实现get()、post()等方法,而是实现动作 action 如 list() 、create() 等

  • 视图集只在使用as_view()方法的时候,才会将action动作与具体请求方式对应上

  • action

    • 在视图集中,我们可以通过action对象属性来获取当前请求视图集时的action动作是哪个。
  • 常用是视图集父类

    • ViewSet

      • 继承自APIView,作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。

在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法

- GenericViewSet

	- 继承自GenericAPIView,作用也与GenericAPIVIew类似,提供了get_object、get_queryset等方法便于列表视图与详情信息视图的开发。

- ModelViewSet

	- 继承自GenericAPIVIew,同时包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。

- ReadOnlyModelViewSet

	- 继承自GenericAPIVIew,同时包括了ListModelMixin、RetrieveModelMixin。
  • 视图集中定义添加action动作

    • 添加自定义动作需要使用rest_framework.decorators.action装饰器

    • action装饰器

      • 以action装饰器装饰的方法名会作为action动作名,与list、retrieve等同

      • methods

        • 该action支持的请求方式,以列表的形式传递
      • detail

        • 表示是action中要处理的是否是视图资源的对象(即是否通过url路径获取主键)

        • True

          • 表示使用通过URL获取的主键对应的数据对象
        • False

          • 表示不使用URL获取主键
      • URL的定义

        • 需要在as_view()中传入以字典的形式的参数,请求方式为键,action为值
  • 路由 Routers

    • 对于视图集ViewSet,我们除了可以自己手动指明请求方式与动作action之间的对应关系外,还可以使用Routers来帮助我们快速实现路由信息。

    • SimpleRouter

    • DefaultRouter

    • 使用方法

      • 1、创建router对象,并注册视图集

        from rest_framework import routers

        注册视图集

        router = router.SimpleRouter()
        router.register(r’路由规则’,要注册的视图集,路由名称的前缀)

      • 对上参数说明

        • register(prefix, viewset, base_name)

        • prefix

          • 该视图集的路由前缀
        • viewset

          • 要注册的视图集
        • base_name

          • 路由名称的前缀
      • 2、添加路由数据

        • urlpatterns = [

          ]
          urlpatterns += router.urls
        • urlpatterns = [

          url(r’^’, include(router.urls))
          ]
    • 视图集中包含附加action的

      • 代码:

        class BookInfoViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
        queryset = BookInfo.objects.all()
        serializer_class = BookInfoSerializer

        @action(methods=['get'], detail=False)
        def latest(self, request):
            ...
        
        @action(methods=['put'], detail=True)
        def read(self, request, pk):
            ...
        
      • 最终会形成的路由

        ^books/latest/$ name: book-latest
        ^books/{pk}/read/$ name: book-read

  • 路由router形成URL的方式

    • SImpleRouter[外链图片转存失败(img-d2qh0Qkx-1564366801230)(assets/187f7953da688214af6f0afd9bac1260b569a62c9e926cb16bdbe038b8db4bef.png)]
    • DefaulfRouter[外链图片转存失败(img-inMj6IWO-1564366801230)(assets/13819fa2722e1627faae5486e8a43076eced699da709d5a155bd49fdbd40c80c.png)]

其它功能

认证 Authentication

  • 1、可以在配置文件中配置全局默认的认证方案

    REST_FRAMEWORK = {
    ‘DEFAULT_AUTHENTICATION_CLASSES’: (
    ‘rest_framework.authentication.BasicAuthentication’, # 基本认证
    ‘rest_framework.authentication.SessionAuthentication’, # session认证
    )
    }

  • 2、也可以通过在每个视图中通过设置authentication_classess属性来设置

    from rest_framework.authentication import SessionAuthentication, BasicAuthentication
    from rest_framework.views import APIView

    class ExampleView(APIView):
    authentication_classes = (SessionAuthentication, BasicAuthentication)

  • 认证失败会有两种可能的返回值

    • 401 Unauthorized 未认证
    • 403 Permission Denied 权限被禁止

权限Permissions

  • 权限控制可以限制用户对于视图的访问和对于具体数据对象的访问

    • 在执行视图的dispatch()方法前,会先进行视图访问权限的判断
    • 在通过get_object()获取具体对象时,会进行对象访问权限的判断
  • 使用

    • ①可以在配置文件中设置默认的权限管理类

      REST_FRAMEWORK = {
      ‘DEFAULT_PERMISSION_CLASSES’: (
      ‘rest_framework.permissions.IsAuthenticated’,
      )
      }

    • ②如果未指明,采用这个配置

      ‘DEFAULT_PERMISSION_CLASSES’: (
      ‘rest_framework.permissions.AllowAny’,
      )

    • ③可以在具体的视图中通过permission_classes属性来设置

      from rest_framework.permissions import IsAuthenticated
      from rest_framework.views import APIView

      class ExampleView(APIView):
      permission_classes = (IsAuthenticated,)

  • 提供的权限

    • AllowAny 允许所有用户
    • IsAuthenticated 仅通过认证的用户
    • IsAdminUser 仅管理员用户
    • IsAuthenticatedOrReadOnly 认证的用户可以完全操作,否则只能get读取

限流Throttling

  • 可以对接口访问的频次进行限制,来减轻服务器压力

  • 使用

    • 全局配置

      REST_FRAMEWORK = {
      ‘DEFAULT_THROTTLE_CLASSES’: (
      ‘rest_framework.throttling.AnonRateThrottle’,
      ‘rest_framework.throttling.UserRateThrottle’
      ),
      ‘DEFAULT_THROTTLE_RATES’: {
      ‘anon’: ‘100/day’,
      ‘user’: ‘1000/day’
      }
      }

      • 在配置文件中,使用DEFAULT_THROTTLE_CLASSES 和 DEFAULT_THROTTLE_RATES进行全局配置,
      • DEFAULT_THROTTLE_RATES可以使用 second,minute,hour或day来指明周期
    • 局部使用

      from rest_framework.throttling import UserRateThrottle
      from rest_framework.views import APIView

      class ExampleView(APIView):
      throttle_classes = (UserRateThrottle,)

      • 在具体视图中通过throttle_classes属性配置
    • 可选限流类

      • AnonRateThrottle

        • 限制所有匿名未认证用户,使用IP区分用户
        • 使用DEFAULT_THROTTLE_RATES[‘anon’] 来设置频次
      • UserRateThrottle

        • 限制认证用户,使用User id 来区分
        • 使用DEFAULT_THROTTLE_RATES[‘user’]来设置频次
      • ScopedRateThrottle

        • 限制用户对于每个视图的访问频次,使用ip或user id

过滤Filtering

  • 对于列表数据可能需要根据字段进行过滤,我们可以通过添加django-fitlter扩展来增强支持。

  • 使用

    • 下载django-filter

      • pip install django-filter
    • 在配置文件中增加过滤后端的设置

      INSTALLED_APPS = [

      ‘django_filters’, # 需要注册应用,
      ]

      REST_FRAMEWORK = {
      ‘DEFAULT_FILTER_BACKENDS’: (‘django_filters.rest_framework.DjangoFilterBackend’,)
      }

    • 在视图中添加filter_fields属性,指定可以过滤的字段

      class BookListView(ListAPIView):
      queryset = BookInfo.objects.all()
      serializer_class = BookInfoSerializer
      filter_fields = (‘btitle’, ‘bread’)

排序

  • 对于列表数据,REST framework提供了OrderingFilter过滤器来帮助我们快速指明数据按照指定字段进行排序。

  • 使用

    class BookListView(ListAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer
    filter_backends = [OrderingFilter]
    ordering_fields = (‘id’, ‘bread’, ‘bpub_date’)

    • 在类视图设置filter_backends

    • 使用rest_framework.filters.OrderingFilter过滤器

    • REST framework会在请求的查询字符串参数中检查是否包含了ordering参数,

      • 如果包含了ordering参数,就按照ordering参数指明的排序字段对数据集进行排序
    • 前端可以传递的ordering参数的可选字段值需要在ordering_fields中指明

分页 Pagination

  • 全局分页

    REST_FRAMEWORK = {
    ‘DEFAULT_PAGINATION_CLASS’: ‘rest_framework.pagination.PageNumberPagination’,
    ‘PAGE_SIZE’: 100 # 每页数目
    }

    • 可以在配置文件中设置全局的分页方式
  • 局部分页

    class LargeResultsSetPagination(PageNumberPagination):
    page_size = 1000
    page_size_query_param = ‘page_size’
    max_page_size = 10000

    • 可以通过自定义Pagination类,来为视图添加不同分页行为,在视图中通过pagination_class属性来指明

      class BookDetailView(RetrieveAPIView):
      queryset = BookInfo.objects.all()
      serializer_class = BookInfoSerializer
      pagination_class = LargeResultsSetPagination

    • 如果在视图内关闭分页功能,只需在视图内设置

      • pagination_class=None
  • 可选分页器

    • PageNumberPagination

      • 前端访问网址形式

      • 可以在子类中定义的属性

        • page_size

          • 每页数目
        • page_query_param

          • 前端发送的页数关键字名,默认为“page”
        • page_size_query_param

          • 前端发送的每页数目关键字名,默认为None
        • max_page_size

          • 前端最多能设置的每页数量
    • LimitOffsetPagination

      • 前端访问网址形式

      • 可以在子类中定义的属性

        • default_limit

          • 默认限制,默认值与PAGE_SIZE设置一致
        • limit_query_param

          • limit参数名,默认为limit
        • offset_query_param

          • offset参数名,默认为offset
        • max_limit

          • 最大limit限制,默认为None

异常处理

  • DRF提供了异常处理,可以自定义异常处理函数

    from rest_framework.views import exception_handler

    def custom_exception_handler(exc, context):
    # 先调用REST framework默认的异常处理方法获得标准错误响应对象
    response = exception_handler(exc, context)

    # 在此处补充自定义的异常处理
    if response is not None:
        response.data['status_code'] = response.status_code
    
    return response
    
  • 使用

    • 在配置文件中声明自定义的异常处理

      REST_FRAMEWORK = {
      ‘EXCEPTION_HANDLER’: ‘my_project.my_app.utils.custom_exception_handler’
      }

    • 如果未声明,会采用默认的方式

      REST_FRAMEWORK = {
      ‘EXCEPTION_HANDLER’: ‘rest_framework.views.exception_handler’
      }

  • REST framework定义的异常

    • APIException

      • 所有异常的父类
    • ParseError

      • 解析错误
    • AuthenticationFailed

      • 认证错误
    • NotAuthenticated

      • 尚未认证
    • PermissionDenied

      • 权限拒绝
    • NotFound

      • 未找到
    • MethodNotAllowed

      • 请求方式不支持
    • NotAcceptable

      • 要获取的数据格式不支持
    • Throttled

      • 超过限流次数
    • ValidationError

      • 检验失败

自动生成接口文档

  • 1、安装依赖

    • REST framework生成接口文档需要coreapi库的支持
    • pip install coreapi
  • 2、设置接口文档访问路径

    • 在总路由中添加接口文档路径

    • 文档路由对应的视图配置为rest_framework.documentation

    • 路径

      • from rest_framework.documentation import include_docs_urls

urlpatterns = [

url(r’^路由匹配’, include_docs_urls(接口文档网站的标题=‘My API title’))
]

  • 3、文档描述说明的定义位置

    • ①单一方法的视图,可直接使用诶视图的文档字符串

      class BookListView(generics.ListAPIView):
      “”"
      返回所有图书信息.
      “”"

    • ②包含多个方法的视图,在类视图的文档字符串中,分开方法定义

      class BookListCreateView(generics.ListCreateAPIView):
      “”"
      get:
      返回所有图书信息.

      post:
      新建图书.
      """
      
    • ③对于视图集ViewSet,仍在类视图的文档字符串中分开定义,但是应使用action名称区分

  • 4、访问接口文档网页

    • ① 视图集ViewSet中的retrieve名称,在接口文档网站中叫做read
    • ②参数的Description需要在模型类或序列化器类的字段中以help_text选项定义

XMind: ZEN - Trial Version

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Django REST Framework 提供了多种方式来设置接口权限: 1. 基于视图函数的权限控制 可以在视图函数中通过 `permission_classes` 属性设置权限类,例如: ```python from rest_framework.permissions import IsAuthenticated from rest_framework.decorators import api_view, permission_classes from rest_framework.response import Response @api_view(['GET']) @permission_classes([IsAuthenticated]) def my_view(request): # 只有已认证用户才能访问 return Response({'message': 'Hello, World!'}) ``` 2. 基于视图类的权限控制 也可以在视图类中通过 `permission_classes` 属性设置权限类,例如: ```python from rest_framework.permissions import IsAuthenticated from rest_framework.views import APIView from rest_framework.response import Response class MyView(APIView): permission_classes = [IsAuthenticated] def get(self, request): # 只有已认证用户才能访问 return Response({'message': 'Hello, World!'}) ``` 3. 全局权限控制 可以在 `settings.py` 文件中通过 `DEFAULT_PERMISSION_CLASSES` 设置全局权限类,例如: ```python REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ] } ``` 这样所有的视图函数和视图类都会使用 `IsAuthenticated` 权限类进行权限控制。 4. 自定义权限类 除了使用 Django REST Framework 提供的权限类外,还可以自定义权限类。自定义权限类需要实现 `BasePermission` 类,并实现 `has_permission` 方法,例如: ```python from rest_framework.permissions import BasePermission class MyPermission(BasePermission): def has_permission(self, request, view): # 自定义权限控制逻辑 return True ``` 然后在视图函数或视图类中使用: ```python @api_view(['GET']) @permission_classes([MyPermission]) def my_view(request): # 自定义权限控制逻辑 return Response({'message': 'Hello, World!'}) ``` 或者在全局设置中使用: ```python REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ 'path.to.MyPermission', ] } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值