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