1 drf之请求
1.1请求源码分析
导入:from rest_framework.request import Request
- 以后视图类的方法中的request都是这个类的对象
- 以后使用
request.data
取请求体中的数据 - 以后使用
request.query_params
取请参数中的数据 - 以后其他属性,用起来跟之前一样—》重要
request.method
的时候—》实际上request._request.'method'
—》反射出来的
这个类from rest_framework.request import Request
没有method,他会触发这个类的__getattr__
- FILES 用起来跟之前一样,前端传入的文件在里面
1.2 drf 之请求Request类
data
query_params
用起来跟之前一样
了解:
request._request
视图类的方法中: self 是咱们写的视图类的对象,self.request 是新的request
1.3 控制前端请求的编码格式
前端传入的编码:urlencoded ,josn ,form-data
如何某些接口只能接收某种编码的处理方式?
方法一:
局部使用,在视图类上配置
# 导入
from rest_framework.parsers import JSONParser, FormParser, MultiPartParser
# JSONParser:json格式
# FormParser:urlencoded格式
# MultiPartParser:form—data格式
class BookView(GenericAPIView,CreateModelMixin,ListModelMixin):
# 允许哪个就在列表里添加哪个
parser_classes = [JSONParser, FormParser]
方法二:
全局都生效,所有接口都支持某一种或某几种
在settings.py
文件中添加
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
# 'rest_framework.parsers.MultiPartParser'
]
}
补充
全局使用后,局部再限制,只需要在视图类上加即可
class BookView(APIView): # 全局如果用了,局部这样配,优先用局部的,也就是这个类管理的接口,只能接收form-data格式
parser_classes = [MultiPartParser]
为什么我们没有配置,三种也支持?
drf自己有默认配置—》默认配置就是支持三种
2 drf之响应
2.1 drf之Response对象源码
导入:from rest_framework.response import Response
返回Response的时候有几个默认参数
def get(self, request):
return Response(data={},status=500,headers={'xxx':'yyy'})
data=None
字符串,列表,字典,放在了响应体中,第一个参数是它status=None
http响应状态码,默认是200,千万不能写成1xxheaders=None
http响应头,后期我们可以往响应头中放数据content_type=None
响应编码格式(不用管,用浏览器访问就是:text/html,用postman就是:json格式)template_name=None
模版名字 默认是:rest_framework/api.html 了解,可以定制自己返回的页面样子
补充
# 后面会用---》通过res.data 就能取到当时放的data
res=Response(data={},status=500,headers={'xxx':'yyy'})
print(res.data)
return res
### 取当时放的响应头
res.headers 拿不到数据,可以通过下面的方式或得到
print(res['xxx'])
print(res.has_header('zzz'))
2.2 drf之响应格式
响应有编码格式:默认支持json和text/html(浏览器)
postman只支持json格式,浏览器优先text/html
局部使用
from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer
# JSONRenderer:json格式
# BrowsableAPIRenderer:模版网页格式
class BookView(APIView):
renderer_classes = [BrowsableAPIRenderer]
全局使用
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
],
}
局部禁用
全局已经配置了—》局部想用浏览器的样子
在settings.py
文件中添加
class BookView(APIView):
renderer_classes = [BrowsableAPIRenderer]
补充
如果不配置,有默认
- 解析:三种编码都能解析
- 响应:浏览器访问看到浏览器的样子,postman访问,看到json格式
3 两个视图基类
- Book 的 5个接口 基于APIView编写
- Publish 的5个接口 基于GenericAPIView编写
3.1 基于GenericAPIView(只要跟数据库打交道)
# 基于GenericAPIView
# 自己写GenericAPIView
from rest_framework.views import APIView
class GenericAPIView(APIView):
queryset = None
serializer_class = None
def get_serializer(self, *args, **kwargs):
return self.serializer_class(*args, **kwargs)
# 方便拓展,方便重写拿到不一样的数据
def get_queryset(self):
return self.queryset.all()
# 真正使用的时候,再加all获取所有才行
def get_object(self, pk):
res = self.queryset()
return res.filter(pk=pk).first()
from .models import Book
from .serializer import BookSerializer
class BookView(GenericAPIView):
# 类只要加载,就会执行,查了所有数据,不能以它为准
queryset = Book.objects.all()
serializer_class = BookSerializer
def get(self, request):
# 以用的时候为准
obj_list = self.get_queryset()
ser = self.get_serializer(instance=obj_list, many=True)
return Response(ser.data)
def post(self, request):
ser = self.get_serializer(data=request.data)
if ser.is_valiad():
ser.save()
return Response(ser.data)
else:
return Response(ser.errors)
class BookDetailView(GenericAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
def get(self, request, pk):
obj = self.get_object(pk)
ser = self.get_serializer(instance=obj)
return Response(ser.data)
def put(self, request, pk):
obj = self.get_object(pk)
ser = self.get_serializer(data=request.data, instance=obj)
if ser.is_valiad():
ser.save()
return Response(ser.data)
else:
return Response(ser.errors)
def delete(self, request, pk):
self.get_object(pk).detele()
return Response("")
3.2 GenericAPIView 有类属性和方法
重要属性
queryset
:以后放所有某个表查询出的数据serializer_class
:要序列化的类
重要方法
get_queryset
:要序列化的所有数据,qs对象get_serializer
:序列化类get_object
:查询的单条
了解类属性
lookup_field = 'pk'
:路由使用转换器,转换出来的参数,查询单条要用到,如果改了,路由对应也要修改,一般不改filter_backends
:后面详细讲 过滤 功能pagination_class
:后面详细讲 分页
了解方法
get_serializer_class
后期咱们可能会重写它,指定某些方法使用不同的序列化类filter_queryset
后面跟过滤功能一起讲
4 5个视图扩展类(不是视图类,先继承GenericAPIView)
drf自己提供了5个视图拓展类,我们只要在视图类中继承使用就行
4.1 继承
RetrieveModelMixin
查询一条,写了一个方法retrieve
,代码就是 跟咱们之前写获取单条get方法内容一样CreateModelMixin
新增一条写了一个方法create
,代码就是 跟咱们之前写新增一条 post 方法内容一样DestroyModelMixin
删除一条写了一个方法destroy
,代码就是 跟咱们之前写删除一条 delete 方法内容一样ListModelMixin
查询所有写了一个方法list
,代码就是 跟咱们之前写查询所有 get 方法内容一样UpdateModelMixin
修改一个写了一个方法update
,代码就是 跟咱们之前写修改一条put 方法内容一样
为什么写5个,不写俩?
因为后期不一定 5个接口都写
4.2 代码
## 基于基于 5个视图扩展类(不是视图类--》先继承GenericAPIView)
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import RetrieveModelMixin, CreateModelMixin,DestroyModelMixin,ListModelMixin,UpdateModelMixin
from .models import Book
from .serializer import BookSerializer
from rest_framework.parsers import JSONParser, FormParser, MultiPartParser
class BookView(GenericAPIView,CreateModelMixin,ListModelMixin):
parser_classes = [JSONParser, FormParser]
queryset = Book.objects.all()
serializer_class = BookSerializer
def get(self, request):
return self.list(request)
def post(self, request):
return self.create(request)
class BookDetailView(GenericAPIView,RetrieveModelMixin,DestroyModelMixin,UpdateModelMixin):
queryset = Book.objects.all()
serializer_class = BookSerializer
def get(self, request, pk):
return self.retrieve(request, pk)
def put(self, request, pk):
return self.update(request, pk)
def delete(self, request, pk):
return self.destroy(request, pk)