drf 的请求与响应
Request类与Response类
- rest_framework类下的
<1> Request类
1.1 .data
- request.data返回解析后的请求体数据特性有
- 包含了对POST,PUT,PATCH请求方式解析后的数据
- 包含了解析之后的文件与非文件数据
- 利用了REST framwork的parsers解析器,支持表单数据类型也支持JSON数据
1.2 .query_params
- 与前面的request.GET用法相同,更换了名称
- 底层原理其实就是反射__getattr__
<2> Response类
2.1 参数
- Response类里面有七个参数
class Response(SimpleTemplateResponse):
def __init__(self, data=None, status=None,
template_name=None, headers=None,
exception=False, content_type=None):
2.2 data
- data=None
- data可以将字典,列表序列化为json格式的字符串,返回给前端(放在http响应的body中)
- status=None
- status为状态码,默认为200
- drf可以把http状态响应码做成常量,导入 rest_framework.status
- headers=None
- 存放http响应头的字典
- template_name=None
- 了解: 模板名称,如果使用HTMLRenderer 时需指明
- content_type=None
- 代表的是响应的编码格式
2.3 状态码
- 1.信息告知 - 1xx
HTTP_100_CONTINUE
HTTP_101_SWITCHING_PROTOCOLS
- 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.重定向 - 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
- 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
- 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
drf能够解析的请求编码与响应编码
1.drf能够解析的请求编码
- urlencoded
- form-data
- json
- 1.1 drf有两套配置
- 一套是drf项目中的settings.py配置,一套是默认的
- 找到drf项目中的settings.py配置:
-
drf中点击rest_framework源码中的settings,找到DEFAULT_PARSER_CLASSES
'DEFAULT_PARSER_CLASSES': [ 'rest_framework.parsers.JSONParser', # 可以解析json格式 'rest_framework.parsers.FormParser', # 可以解析urlencoded格式 'rest_framework.parsers.MultiPartParser' # 可以解析form-data格式 ],
- 全局配置:
- 接口只接受json格式的需要在django的settings中配置上面的配置,注掉下面两种格式即可
- 局部配置:视图类自己写
class TestView(APIView): parser_classes = [JSONParser,FormParser,MultiPartParser]
- 全局配置:
-
解析类的使用顺序
- 优先使用:
- 视图类自己的 > 项目配置文件 > drf’内置
项目的实际配置
- 基本上都运行JSONParser,FormParser
- 如果上传文件只允许MultiPartParser
2.响应编码格式
-
默认情况下的响应的编码是根据客户端类型决定的
- 例: 如果用浏览器,好看的样子,如果用postman看到json格式
-
全局配置:在项目的配置文件的settings根据需求注释
'DEFAULT_RENDERER_CLASSES': [ 'rest_framework.renderers.JSONRenderer', # json格式 'rest_framework.renderers.BrowsableAPIRenderer', # 浏览器的格式 ],
-
局部配置:
class TestView(APIView): renderer_classes = [JSONRenderer,]`
drf的视图组件
> 1. drf提供了一个顶层的视图类APIView,我们通过继承APIView写视图类
> 2. 重复的代码出现较多时,要熟练的使用面向对象的继承与封装
drf两个视图基类
APIView
GenericAPIView:(继承于APIView)
基于APIView写5个接口
models.py(模型层)
- 要进行数据迁移
from django.db import models
class Book(models.Model):
name = models.CharField(max_length=32)
price = models.CharField(max_length=32)
publish = models.CharField(max_length=32)
views.py(视图层)
from .models import Book
from rest_framework.views import APIView,Response
from .serializer import BookSerializer
class Bookview(APIView):
def get(self,request):
book_list=Book.objects.all()
ser = BookSerializer(instance=book_list,many=True)
return Response(ser.data)
def post(self,request):
ser=BookSerializer(data=request.data)
if ser.is_valid():
ser.save()
return Response({'code':100, 'msg':"新建成功"},status=201)
else:
return Response({'code':101, 'msg':ser.errors})
class BookDetailView(APIView):
def get(self,request,pk):
book= Book.objects.filter(pk=pk).first()
ser = BookSerializer(instance=book)
return Response(ser.data)
def put(self,request,pk):
book = Book.objects.filter(pk=pk).first()
ser = BookSerializer(instance=book,data=request.data)
if ser.is_valid():
ser.save()
return Response({'code':100,'msg':"修改成功"},status=201)
else:
return Response({'code':100,'msg':ser.errors})
def delete(self,request,pk):
Book.objects.filter(pk=pk).delete()
return Response('')
serializer.py
from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = '__all__'
路由层
from app01 import views
urlpatterns = [
path('books/',views.Bookview.as_view()),
path('books/<int:pk>', views.BookDetailView.as_view())
]
基于GenericAPIView写5个接口
- GenericAPIView源码中封装的方法
models.py
from django.db import models
class User(models.Model):
name = models.CharField(max_length=32)
age = models.CharField(max_length=32)
gender = models.CharField(max_length=32)
views.py
from .models import User
from rest_framework.views import APIView,Response
from .serializer import UserSerializer
from rest_framework.generics import GenericAPIView
class Userview(GenericAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
def get(self,request):
user_list= self.get_queryset()
ser = self.get_serializer(instance=user_list,many=True)
return Response(ser.data)
def post(self,request):
ser= self.get_serializer(data=request.data)
if ser.is_valid():
ser.save()
return Response({'code':100, 'msg':"新建成功"},status=201)
else:
return Response({'code':101, 'msg':ser.errors})
class UserDetailView(GenericAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
def get(self,request,pk):
user= self.get_object()
ser = self.get_serializer(instance=user)
return Response(ser.data)
def put(self,request,pk):
user = self.get_object()
ser = self.get_serializer(instance=user,data=request.data)
if ser.is_valid():
ser.save()
return Response({'code':100,'msg':"修改成功"},status=201)
else:
return Response({'code':100,'msg':ser.errors})
def delete(self,request,pk):
self.get_queryset().filter(pk=pk).delete()
return Response('')
serializer.py
from rest_framework import serializers
from .models import User
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = '__all__'
路由层
from app01 import views
urlpatterns = [
path('users/', views.Userview.as_view()),
path('users/<int:pk>', views.UserDetailView.as_view())
]