3.1 信息告知---1XX
HTTP_100_CONTINUE
HTTP_101_SWITCHING_PROTOCOLS
3.2 成功---2XX
HTTP_200_OK
HTTP_201_CREATED
HTTP_202_ACCEPTED
HTTP_203_NON_AUTHORITATIVE_INFORMATION
HTTP_204_NO_CONTENT
HTTP_205_RESET_CONTENT
HTTP_206_PARTIAL_CONTENT
HTTP_207_MULTI_STATUS
3.3 重定向---3XX
HTTP_300_MULTIPLE_CHOICES
HTTP_301_MOVED_PERMANENTLY
HTTP_302_FOUND
HTTP_303_SEE_OTHER
HTTP_304_NOT_MODIFIED
HTTP_305_USE_PROXY
HTTP_306_RESERVED
HTTP_307_TEMPORARY_REDIRECT
3.4 客户端错误---4XX
HTTP_400_BAD_REQUEST
HTTP_401_UNAUTHORIZED
HTTP_402_PAYMENT_REQUIRED
HTTP_403_FORBIDDEN
HTTP_404_NOT_FOUND
HTTP_405_METHOD_NOT_ALLOWED
HTTP_406_NOT_ACCEPTABLE
HTTP_407_PROXY_AUTHENTICATION_REQUIRED
HTTP_408_REQUEST_TIMEOUT
HTTP_409_CONFLICT
HTTP_410_GONE
HTTP_411_LENGTH_REQUIRED
HTTP_412_PRECONDITION_FAILED
HTTP_413_REQUEST_ENTITY_TOO_LARGE
HTTP_414_REQUEST_URI_TOO_LONG
HTTP_415_UNSUPPORTED_MEDIA_TYPE
HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE
HTTP_417_EXPECTATION_FAILED
HTTP_422_UNPROCESSABLE_ENTITY
HTTP_423_LOCKED
HTTP_424_FAILED_DEPENDENCY
HTTP_428_PRECONDITION_REQUIRED
HTTP_429_TOO_MANY_REQUESTS
HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE
HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS
3.5 服务器错误---5XX
HTTP_500_INTERNAL_SERVER_ERROR
HTTP_501_NOT_IMPLEMENTED
HTTP_502_BAD_GATEWAY
HTTP_503_SERVICE_UNAVAILABLE
HTTP_504_GATEWAY_TIMEOUT
HTTP_505_HTTP_VERSION_NOT_SUPPORTED
HTTP_507_INSUFFICIENT_STORAGE
HTTP_511_NETWORK_AUTHENTICATION_REQUIRED
具体代码参考:https://www.cnblogs.com/Michael--chen/p/11235456.html
用到的序列化器类:
from students.models import Student from rest_framework import serializers class StudentModelSerializer(serializers.ModelSerializer): class Meta: model = Student fields = ["id", "name", "age", "sex"] extra_kwargs = { "name": {"max_length": 10, "min_length": 4}, "age": {"max_value": 150, "min_value": 0}, } def validate_name(self, data): if data == "root": raise serializers.ValidationError("用户名不能为root!") return data def validate(self, attrs): name = attrs.get('name') age = attrs.get('age') if name == "alex" and age == 22: raise serializers.ValidationError("alex在22时的故事。。。") return attrs
对应的urls的文件:
urlpatterns = [ # View与APIView的区别 path("student1/", views.Student1View.as_view()), path("student2/", views.Student2APIView.as_view()), ]
views.py文件:
from django.views import View from django.http import JsonResponse class Student1View(View): def get(self, request): print(request) # 这是django提供的HttpRequest类 print(request.GET) """打印效果: <WSGIRequest: GET '/req/student1/'> """ data_dict = {'name': "alex", "age": 18} return JsonResponse(data_dict) from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status class Student2APIView(APIView): def get(self, request): print(request) # rest_framework扩展后的request print(request.query_params) print(request.data) """打印效果 <rest_framework.request.Request object at 0x00000000054D8898> """ data_dict = {'name': "alex", "age": 18} return Response(data_dict, status=status.HTTP_204_NO_CONTENT, headers={"name": "xiaobai"})
小结: 1.使用Django的View时候, 导包: from django.views import View from django.http import JsonResponse 最初的老办法一步一步开 2.使用drf的View时候: from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status 3.返回的方式是drf是根据你的需要就行返回,比较灵活。
urls.py中的文件: path("student4/", views.Student5GenericAPIView.as_view()), re_path(r"^student4/(?P<pk>\d+)/$", views.Student6GenericAPIView.as_view()), ]
下图中的5改为4.
小结:1.最大改变是
# 当前视图类中操作的公共数据,先从数据库查询出来 queryset = Student.objects.all() # 设置类视图中所有方法共有调用的序列化器类 serializer_class = StudentModelSerializer
2.调用值的方式的改变。从GenericAPIView开始发生变化
#1.self.get_queryset() 获取数据库中的所有对象
# 类似于之前的在数据库中查询:
student_list = Student.objects.all()这个也是和APIView的区别。
# 2.# 调用序列化器 serializer = self.get_serializer(instance=student_list, many=True)
在4的基础上就行再次的封装!
# 不带参数的,GenericApIView的
# 带参数的
# 和不带参数的GenericApIView加上同样的2条之后还有第三条:
#1. # 获取pk值对应的对象 instance = self.get_object() # 2.生成serializer对象时候,和上面差不多 serializer = self.get_serializer(instance=instance, data=request.data) # 3. pk值是没有管的,直接获取self.get_object()
class Student6GenericAPIView(GenericAPIView): # 当前视图类中操作的公共数据,先从数据库查询出来 queryset = Student.objects.all() # 设置类视图中所有方法共有调用的序列化器类 serializer_class = StudentModelSerializer def get(self, request, pk): """参数pk名,必须要叫pk,否则会报错。""" # 获取模型对象 instance = self.get_object() serializer = self.get_serializer(instance=instance) return Response(serializer.data) def put(self, request, pk): instance = self.get_object() serializer = self.get_serializer(instance=instance, data=request.data) serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data) def delete(self, request, pk): # 获取模型对象 instance = self.get_object() # 删除模型对象 instance.delete() return Response(status=status.HTTP_204_NO_CONTENT)
在上面5的基础上就行进一步的封装.
url中的代码:
path("student5/", views.Student7GenericAPIView.as_view()), 不带参数的是访问模式可以是最开始的Get获取所有数据功能,POST增加单条数据。 re_path(r"^student5/(?P<pk>\d+)/$", views.Student8GenericAPIView.as_view()),# 带参数的,可以是对应到最开始的PUT/Delete/update对应到这个地方封装的
ListModelMixin 实现查询所有数据功能 get CreateModelMixin 实现添加数据的功能 post RetrieveModelMixin 实现查询一条数据功能get UpdateModelMixin 更新一条数据的功能 update DestroyModelMixin 删除一条数据的功能 destroy
from rest_framework.mixins import ListModelMixin, CreateModelMixin class Student7GenericAPIView(GenericAPIView, ListModelMixin, CreateModelMixin): queryset = Student.objects.all() serializer_class = StudentModelSerializer def get(self, request): return self.list(request) def post(self, request): return self.create(request) from rest_framework.mixins import RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin class Student8GenericAPIView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin): queryset = Student.objects.all() serializer_class = StudentModelSerializer def get(self, request, pk): return self.retrieve(request) def put(self, request, pk): return self.update(request) def delete(self, request, pk): return self.destroy(request)
小结:中间代码的环节不用写了,在内部封装好了!
比如上面的get方法中的
def get(self, request, pk): """参数pk名,必须要叫pk,否则会报错。""" # 获取模型对象 instance = self.get_object() serializer = self.get_serializer(instance=instance) return Response(serializer.data)
只需要写出函数名和返回值即可。
urls.py中的代码:
# 使用内置的扩展子类,生成API接口 path("student6/", views.Student9GenericAPIView.as_view()), re_path(r"^student6/(?P<pk>\d+)/$", views.Student10GenericAPIView.as_view()),
在6的基础上就行封装!
""" DRF里面,内置了一些同时继承了GenericAPIView和Mixins扩展类的视图子类, 我们可以直接继承这些子类就可以生成对应的API接口 """ """ ListAPIView 获取所有数据 CreateAPIView 添加数据 """ from rest_framework.generics import ListAPIView, CreateAPIView class Student9GenericAPIView(ListAPIView, CreateAPIView): queryset = Student.objects.all() serializer_class = StudentModelSerializer """ RetrieveAPIView 获取一条数据 UpdateAPIView 更新一条数据 DestorAPIView 删除一条数据 RetrieveUpdateDestoryAPIView 上面三个的缩写 """ from rest_framework.generics import RetrieveUpdateDestroyAPIView class Student10GenericAPIView(RetrieveUpdateDestroyAPIView): queryset = Student.objects.all() serializer_class = StudentModelSerializer 复制代码
视图集 上面5个接口使用了8行代码生成,但是我们可以发现有一半的代码重复了 所以,我们要把这些重复的代码进行整合,但是依靠原来的类视图,其实有2方面产生冲突的 1. 查询所有数据、添加数据是不需要声明pk的,而其他的接口需要 [路由冲突了] 2. 查询所有数据和查询一条数据,都是属于get请求 [请求方法冲突了] 为了解决上面的2个问题,所以DRF提供了视图集来解决这个问题
urls.py中的代码:
path("student7/", views.Student11GenericAPIView.as_view({"get": "list", "post": "create"})), re_path(r"^student7/(?P<pk>\d+)/$", views.Student11GenericAPIView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),
掌握最后一个就可以了!,直接在视图的位置就行指定,就可以达到对应的访问。无敌!
from rest_framework.viewsets import GenericViewSet, ModelViewSet from rest_framework.mixins import ListModelMixin, CreateModelMixin, DestroyModelMixin, UpdateModelMixin, RetrieveModelMixin # 这两个是等价的 # class Student11GenericAPIView(GenericViewSet, ListModelMixin, CreateModelMixin, DestroyModelMixin, UpdateModelMixin, RetrieveModelMixin): class Student11GenericAPIView(ModelViewSet): queryset = Student.objects.all() serializer_class = StudentModelSerializer