DRF教程2-请求和响应

Request objects

REST framework中有一个Request对象,是HttpRequest的扩展,提供了新的请求解析,Request的核心功能就是request.data,它和request.POST相似,但是在web API中更为有效

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

  

Response objects

REST framework中还有一个Response对象,是一种TemplateResponse ,拿到原始数据并以正确的类型返回给客户端。

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

  

Status codes

在你的视图中,使用数字HTTP状态码不好读,rest使用了更明确的标识符,比如HTTP_400_BAD_REQUEST 。

 

Wrapping API views

rest提供了两种写API视图的包装。

1 @api_view装饰器在函数视图中使用

2 APIView类在类视图中使用

这些包装器提供了一些功能,比如确认在你的视图中接收到了Request实例,并且把上下文添加到Response对象中。

包装器也可以返回405 Method Not Allowed,也可以处理任何在访问有错误的request.data时产生的ParseError 异常

 

Pulling it all together

以上的组件可以使我们重写views。

我们不再需要在views.py加入JSONResponse 类,而是稍微重构views

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

from .models import Course
from .serializer import CourseSerializer

@api_view(["GET","POST"])
def course_list(request,format=None):
    """
    List all courses, or create a new course.
    """
    if request.method == 'GET':
        courses = Course.objects.all()
        serializer = CourseSerializer(courses,many=True)
        return Response(serializer.data)

    elif request.method == 'POST':
        serializer = CourseSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data,status=status.HTTP_201_CREATED)
        return Response(serializer.errors,status=status.HTTP_400_BAD_REQUEST)

@api_view(['GET', 'PUT', 'DELETE'])
def course_detail(request, pk, format=None):
    """
    Retrieve, update or delete a course.
    """
    try:
        snippet = Course.objects.get(pk=pk)
    except Course.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':
        serializer = CourseSerializer(snippet)
        return Response(serializer.data)

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

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

  

from rest_framework.urlpatterns import format_suffix_patterns
from courses import views

urlpatterns = [
    path('course/', views.course_list,name='course_list'),
    path('course/<int:pk>/', views.course_detail,name='course_detail'),
]
urlpatterns = format_suffix_patterns(urlpatterns)
#在views中的函数加入format参数,然后咋url中使用格式后缀模型,对url进行转换,就可以使用带后缀的url请求。

  

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

  

posted @ 2019-03-19 15:09  jabbok  阅读(253)  评论(0编辑  收藏  举报