十八、Django-restframework之请求和响应(三)

1. 请求对象

REST框架引入了一个扩展了常规HttpRequest的请求对象, 并提供更灵活的请求解析。请求对象的核心功能是属性request.data,这与request.POST类似,但对于WebAPIs更有用。

request.POST  # Only handles form data.  Only works for 'POST' method.
request.data  # Handles arbitrary data.  Works for 'POST', 'PUT' and 'PATCH' methods.

2. 响应对象

REST framework还引入了一个响应对象,这是一种TemplateResponse类型,它接受未渲染的内容,并使用内容协商来确定返回给客户端的正确内容类型。

return Response(data)  # Renders to content type as requested by the client.

3. 状态码

在视图中使用数字HTTP状态码并不总是容易读懂,而且当使用了错误的状态码还不容易发现。REST框架为每个状态代码提供了更显式的标识符, 比如status模块中的HTTP_400_BAD_REQUEST

4. 视图包装器

REST框架提供了两个包装器,您可以使用它们来编写API视图。

  • @api_view用来装饰基本的函数视图。
  • APIview类用来创建类视图。

这些包装器提供了一些功能,比如确保在视图中接收到请求实例,并向响应对象添加上下文,以便可以执行内容协商。

包装器还提供了一些行为,比如在适当的时候返回405 Method Not Allowed响应,以及处理当request.data输入不正确数据时发生的任何ParseError异常。

5. 一步到位

from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response


@api_view(['get', 'post'])
def student_list_or_create(request):
    """
    学生列表,学生创建视图
    """
    if request.method == 'GET':
        objs = Student.objects.all()
        serializer = StudentSerializer(objs, many=True)
        return Response(serializer.data)
    elif request.method == 'POST':

        serializer = StudentSerializer(data=request.data)
        # 3. 校验
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET', 'PUT', 'DELETE'])
def Student_detail(request, pk):
    """
    学生详情,学生更新,学生删除
    """
    try:
        obj = Student.objects.get(pk=pk)
    except Student.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':
        serializer = StudentSerializer(obj)
        return Response(serializer.data)

    elif request.method == 'PUT':
        serializer = StudentSerializer(obj, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        obj.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

我们的实例视图是对之前示例的改进。它更简洁了一些,现在的代码感觉非常类似于我们使用表单API时的代码。我们还使用了命名状态码,这使得响应的含义更加明显。

请注意,我们不再显式地将请求或响应绑定到给定的内容类型。request.data可以处理传入的json请求,但它也可以处理其他格式。类似地,我们返回带有数据的响应对象,但允许REST框架为我们将响应呈现为正确的内容类型。

6. 为url添加可选的格式后缀

为了利用我们的响应不再硬连接到单一内容类型这一事实,让我们向API端点添加对格式后缀的支持。使用格式后缀给我们提供了明确引用给定格式的url,这意味着我们的API将能够处理像http://example.com/api/items/4.json这样的url。

首先向两个视图添加一个format关键字参数,如下所示。

def student_list(request, format=None):
def student_detail(request, pk, format=None):

现在稍微更新一下crm/urls.py文件,在现有url之外附加一组format_suffix_patterns

from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from projects import views

urlpatterns = [
    path('students/', views.project_list),
    path('students/<int:pk>', views.project_detail),
]

urlpatterns = format_suffix_patterns(urlpatterns)

我们不需要添加这些额外的url模式,但它为我们提供了一种简单、干净的方法来引用特定的格式。

我们可以通过使用请求头Accept来控制返回响应的格式:

http http://127.0.0.1:8000/students/ Accept:application/json  # Request JSON
http http://127.0.0.1:8000/students/ Accept:text/html         # Request HTML

或通过添加格式后缀:

http http://127.0.0.1:8000/projects.json  # JSON suffix
http http://127.0.0.1:8000/projects.api   # Browsable API suffix

类似地,发送请求时也可处理不同的参数。

 

7. 可浏览

由于API根据客户端请求选择响应的内容类型, 默认情况下,当web浏览器请求该资源时,它将返回该资源的html格式表示。这允许API返回一个完全可网页浏览的HTML表示。

拥有一个可网页浏览的API是一个巨大的可用性胜利,使开发和使用API变得更加容易。它还极大地降低了希望检查和使用您的API的其他开发人员的进入门槛。

有关可浏览api特性和如何自定义的更多信息,请参阅可浏览api主题。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值