restframework中的status

中文文档:https://q1mi.github.io/Django-REST-framework-documentation/tutorial/2-requests-and-responses_zh/

在视图(views)中使用纯数字的HTTP 状态码并不总是那么容易被理解。而且如果错误代码出错,很容易被忽略。REST框架为status模块中的每个状态代码(如HTTP_400_BAD_REQUEST)提供更明确的标识符。使用它们来代替纯数字的HTTP状态码是个很好的主意。

源码:

"""
Descriptive HTTP status codes, for code readability.

See RFC 2616 - https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
And RFC 6585 - https://tools.ietf.org/html/rfc6585
And RFC 4918 - https://tools.ietf.org/html/rfc4918
"""


def is_informational(code):
    return 100 <= code <= 199


def is_success(code):
    return 200 <= code <= 299


def is_redirect(code):
    return 300 <= code <= 399


def is_client_error(code):
    return 400 <= code <= 499


def is_server_error(code):
    return 500 <= code <= 599


HTTP_100_CONTINUE = 100
HTTP_101_SWITCHING_PROTOCOLS = 101
HTTP_200_OK = 200
HTTP_201_CREATED = 201
HTTP_202_ACCEPTED = 202
HTTP_203_NON_AUTHORITATIVE_INFORMATION = 203
HTTP_204_NO_CONTENT = 204
HTTP_205_RESET_CONTENT = 205
HTTP_206_PARTIAL_CONTENT = 206
HTTP_207_MULTI_STATUS = 207
HTTP_208_ALREADY_REPORTED = 208
HTTP_226_IM_USED = 226
HTTP_300_MULTIPLE_CHOICES = 300
HTTP_301_MOVED_PERMANENTLY = 301
HTTP_302_FOUND = 302
HTTP_303_SEE_OTHER = 303
HTTP_304_NOT_MODIFIED = 304
HTTP_305_USE_PROXY = 305
HTTP_306_RESERVED = 306
HTTP_307_TEMPORARY_REDIRECT = 307
HTTP_308_PERMANENT_REDIRECT = 308
HTTP_400_BAD_REQUEST = 400
HTTP_401_UNAUTHORIZED = 401
HTTP_402_PAYMENT_REQUIRED = 402
HTTP_403_FORBIDDEN = 403
HTTP_404_NOT_FOUND = 404
HTTP_405_METHOD_NOT_ALLOWED = 405
HTTP_406_NOT_ACCEPTABLE = 406
HTTP_407_PROXY_AUTHENTICATION_REQUIRED = 407
HTTP_408_REQUEST_TIMEOUT = 408
HTTP_409_CONFLICT = 409
HTTP_410_GONE = 410
HTTP_411_LENGTH_REQUIRED = 411
HTTP_412_PRECONDITION_FAILED = 412
HTTP_413_REQUEST_ENTITY_TOO_LARGE = 413
HTTP_414_REQUEST_URI_TOO_LONG = 414
HTTP_415_UNSUPPORTED_MEDIA_TYPE = 415
HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE = 416
HTTP_417_EXPECTATION_FAILED = 417
HTTP_418_IM_A_TEAPOT = 418
HTTP_422_UNPROCESSABLE_ENTITY = 422
HTTP_423_LOCKED = 423
HTTP_424_FAILED_DEPENDENCY = 424
HTTP_426_UPGRADE_REQUIRED = 426
HTTP_428_PRECONDITION_REQUIRED = 428
HTTP_429_TOO_MANY_REQUESTS = 429
HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE = 431
HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS = 451
HTTP_500_INTERNAL_SERVER_ERROR = 500
HTTP_501_NOT_IMPLEMENTED = 501
HTTP_502_BAD_GATEWAY = 502
HTTP_503_SERVICE_UNAVAILABLE = 503
HTTP_504_GATEWAY_TIMEOUT = 504
HTTP_505_HTTP_VERSION_NOT_SUPPORTED = 505
HTTP_506_VARIANT_ALSO_NEGOTIATES = 506
HTTP_507_INSUFFICIENT_STORAGE = 507
HTTP_508_LOOP_DETECTED = 508
HTTP_509_BANDWIDTH_LIMIT_EXCEEDED = 509
HTTP_510_NOT_EXTENDED = 510
HTTP_511_NETWORK_AUTHENTICATION_REQUIRED = 511

实际上就是一个常量类。

包装(wrapping)API视图

REST框架提供了两个可用于编写API视图的包装器(wrappers)。

  1. 用于基于函数视图的@api_view装饰器。

也就是说可以在原生VIEW视图中,添加@api_view(['GET', 'POST'])就可以将原response封装成rest中的response

  1. 用于基于类视图的APIView类。

这些包装器提供了一些功能,例如确保你在视图中接收到Request实例,并将上下文添加到Response,以便可以执行内容协商。
包装器还提供了诸如在适当时候返回405 Method Not Allowed响应,并处理在使用格式错误的输入来访问request.data时发生的任何ParseError异常。

给我们的网址添加可选的格式后缀

为了充分利用我们的响应不再与单一内容类型连接,我们可以为API路径添加对格式后缀的支持。使用格式后缀给我们明确指定了给定格式的URL,这意味着我们的API将能够处理诸如http://example.com/api/items/4.json之类的URL。

具体看文档:https://q1mi.github.io/Django-REST-framework-documentation/tutorial/2-requests-and-responses_zh/

填坑

填61笔记留下的BUG,新建环境测试

models

models.py:

class Book(models.Model):
    b_name = models.CharField(max_length=16)
    b_price = models.IntegerField(default=1)

迁移数据库

serializers

序列化器
serializers.py

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ('b_name', 'b_price')

views

views:

@api_view(['GET','POST'])
def books(request):
    print(type(request))
    if request.method == 'GET':  # 如果请求方式为get
        return Response({'msg':'ok'}, 200)
    elif request.method == 'POST':
        # 如果请求方式为post,就使用bookserializer序列化传输过来的数据
        print(request.data)
        book_serializer = BookSerializer(data=request.data)
        if book_serializer.is_valid():
            book_serializer.save()
            return Response(book_serializer.data)  # 如果存储数据成功,就返回存储的内容
        # 如果存储出错,就返回错误异常
        return Response(data={'msg':'error'},status=status.HTTP_400_BAD_REQUEST)

urls

path(r'books/', views.books),

使用postman测试


可以看到已经返回我们提前的数据

并且控制台也打印出requests的类型是装饰器封装过的rest的request,并且使用request.data成功打印出数据组。

所以可以利用这种方法一次接受很多字段的数据,并写入数据库。

restframework总结

  • django-rest-framework
  • REST难点

    • 模型序列化

      • 正向序列化

        • 将模型转换成JSON
      • 反向序列化

        • 将JSON转换成模型
    • serialization

      • 在模块serializers

        • HyperLinkedModelSerializer

          • 序列化模型,并添加超链接
        • Serializer

          • 手动序列化
    • 双R

      • Request

        • rest_framework.request
        • 将Django中的Request作为了自己的一个属性 _request
        • 属性和方法

          • content_type
          • stream
          • query_params
          • data

            • 同时兼容  POST,PUT,PATCH
          • user

            • 可以直接在请求上获取用户
            • 相当于在请求上添加一个属性,用户对象
          • auth

            • 认证
            • 相当于请求上添加了一个属性,属性值是token
          • successful_authenticator

            • 认证成功
      • Response

        • 依然是HttpResponse的子类
        • 自己封装的

          • data 直接接受字典转换成JSON
          • status  状态码
        • 属性和方法

          • rendered_content
          • status_text
    • APIView

      • renderer_classes

        • 渲染的类
      • parser_classes

        • 解析转换的类
      • authentication_classes

        • 认证的类
      • throttle_classes

        • 节流的类
        • 控制请求频率的
      • permission_classes

        • 权限的类
      • content_negotiation_class

        • 内容过滤类
      • metadata_class

        • 元信息的类
      • versioning_class

        • 版本控制的类
      • as_view()

        • 调用父类中的as_view -> dispatch

          • dispatch被重写
          • initialize_request

            • 使用django的request构建了一个REST中的Request
          • initial

            • perform_authentication

              • 执行用户认证
              • 遍历我们的认证器

                • 如果认证成功会返回一个元组
                • 元组中的第一个元素就是 user
                • 第二个元素就是 auth,token
            • check_permissions

              • 检查权限
              • 遍历我们的权限检测器

                • 只要有一个权限检测没通过
                • 就直接显示权限被拒绝
                • 所有权限都满足,才算是拥有权限
            • check_throttles

              • 检测频率
              • 遍历频率限制器

                • 如果验证不通过,就需要等待
          • csrf_exempt

            • 所有APIView的子类都是csrf豁免的
    • 错误码

      • 封装 status模块中
      • 实际上就是一个常量类
    • 针对视图函数的包装

      • CBV

        • APIView
      • FBV

        • 添加 @api_view装饰器
        • 必须手动指定允许的请求方法
最后修改:2024 年 03 月 13 日
如果觉得我的文章对你有用,请随意赞赏