Django-RESTful Api 之请求与响应

配置应用

1
2
3
4
5
6
7
8
9
10
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myApp',
'rest_framework',
]

Request 对象

  • request.POST只能处理表单数据,并且只能处理 POST 请求
  • request.data能处理各种请求数据,可以处理 PUT 和 PATCH 请求的数据

Response 对象

  • JsonResponse 类:用于返回 json 格式的响应数据,在 return 的时候需要指明 json 格式
  • Reponse 类:会根据客户端的请求头部信息来返回正确的内容类型

状态码

  • 发送 http 请求是会返回各种各样的状态码,但是都是数字,这些数字不能够明确的让程序员了解错误
  • HTTP_400_BAD_REQUEST 极大的提高可读性

视图

  • @api_view是装饰器,用在基于函数的视图上
  • APIView是类,用在基于类的视图上
  • 注意:提供一些功能,让程序员节省工作量,接收到错误的 request.data 抛出 parseError,或者在适当时候返回 405 状态码

应用扩展

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
from myApp.models import Student, Grade
from myApp.serializers import StudentSerializer
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status


# Create your views here.
@api_view(["GET", "POST"])
def studentsList(request):
if request.method == "GET":
stus = Student.objects.all()
serializer = StudentSerializer(stus, many=True)
# 不需要指定json格式,返回给客户端的可以json也可以是HTML等类型的数据,如果返回会的是HTML,会在浏览器经过渲染展示
return Response(serializer.data, status=status.HTTP_200_OK)
elif request.method == "POST":
serializer = StudentSerializer(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 studentDetail(request, pk):
try:
stu = Student.objects.get(pk=pk)
except Student.DoesNotExist as e:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == "GET":
serializer = StudentSerializer(stu)
return Response(serializer.data, status=status.HTTP_200_OK)
elif request.method == "PUT":
serializer = StudentSerializer(stu, 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)
elif request.method == "DELETE":
stu.delete()
return Response(status=status.HTTP_204_NO_CONTENT)

向 URL 添加可选的格式后缀

  • 视图:

    1
    def studentsList(request, format=None)
    1
    def studentDetail(request, pk, format=None)
  • 路由:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    from django.conf.urls import url
    from myApp import views
    # 格式后缀
    from rest_framework.urlpatterns import format_suffix_patterns

    urlpatterns = [

    url(r'^students/$', views.studentsList),
    url(r'^students/(?P<pk>\d+)', views.studentDetail),
    ]
    urlpatterns = format_suffix_patterns(urlpatterns)
  • 测试:

    1
    2
    http://127.0.0.1:8000/students.api
    http://127.0.0.1:8000/students.json
  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    from myApp.models import Student, Grade
    from myApp.serializers import StudentSerializer
    from rest_framework.decorators import api_view
    from rest_framework.response import Response
    from rest_framework import status


    # Create your views here.
    @api_view(["GET", "POST"])
    def studentsList(request, format=None):
    if request.method == "GET":
    stus = Student.objects.all()
    serializer = StudentSerializer(stus, many=True)
    # 不需要指定json格式,返回给客户端的可以json也可以是HTML等类型的数据,如果返回会的是HTML,会在浏览器经过渲染展示
    return Response(serializer.data, status=status.HTTP_200_OK)
    elif request.method == "POST":
    serializer = StudentSerializer(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 studentDetail(request, pk, format=None):
    try:
    stu = Student.objects.get(pk=pk)
    except Student.DoesNotExist as e:
    return Response(status=status.HTTP_404_NOT_FOUND)
    if request.method == "GET":
    serializer = StudentSerializer(stu)
    return Response(serializer.data, status=status.HTTP_200_OK)
    elif request.method == "PUT":
    serializer = StudentSerializer(stu, 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)
    elif request.method == "DELETE":
    stu.delete()
    return Response(status=status.HTTP_204_NO_CONTENT)