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