昨日回顾
1 序列化类之Serializer(跟表模型没有必然联系)
-写出要序列化的字段(尽量跟模型表的字段类对应)
-source属性(用的很少)
2 字段类
-CharField
-IntegerField
3 字段参数
-通用
-read_only
-write_only
-独有
4 必须重写create和update方法
5 局部,全局钩子函数(反序列化,验证数据)
-validate_字段名(self,item):
校验通过,直接return,校验失败,抛异常
-validate(self,attrs)
校验通过,直接return attrs,校验失败,抛异常
5 序列化类之ModelSerializer(跟表模型没有必然联系)
-写一个内部类
-class Meta:
model=表模型
fields=['字段','方法']
extra_kwargs={'name':{}}
-重写要序列化的字段字段
-要序列化的字段,类是通过表模型映射过来的
6 ModelSerializer不需要重写create和update(ModelSerializer帮我们写了)
7 指定某个字段序列化的格式(两种方法)
-在表模型中写方法(包装成数据属性)
-在序列化类中使用SerializerMethodField
今日内容
1.请求与响应(**)
1.drf的请求
# Request类的对象 方法
-.data:包含了对POST、PUT、PATCH请求方式解析后的数据
-.query_params:Django标准的request.GET
# 通过配置,设置后端接口支持的编码格式
# 默认情况支持三种
-全局配置(在项目的settings.py中)
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser', # json
# 'rest_framework.parsers.FormParser', # urlencoded
# 'rest_framework.parsers.MultiPartParser' # form-data文件格式
]
}
-局部配置(在视图类中写类属性)
class IndexView(APIView):
parser_classes = [JSONParser,] # 只支持json格式
# 查找顺序是先找视图类局部----》项目配置文件中----》drf的配置文件
# drf有内置的配置文件,在drf源码的settings.py中有个DEFAULT字典‘
# 默认解析的编码格式
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser', # json
'rest_framework.parsers.FormParser', # urlencoded
'rest_framework.parsers.MultiPartParser' # form-data文件格式
]
2.响应
# drf的Response类的对象(继承了HttpResponse)
# response对象的属性 (参数)
- data:要返回的数据,放到了http响应的响应体中
- status:http响应的状态码
- drf把所有的状态码都定义成了常量 (在rest_framework.status中)
- 在rest_framework.status中
- headers: http响应头,是个字典
- {'name':'lqz'}
- content_type: 响应编码格式,了解 例:'application/json'、 'text/html'
# 响应显示的格式的局部配置和全局配置
-全局配置(在项目的settings.py中)
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
]
}
-局部配置(在视图类中写类属性)
class IndexView(APIView):
renderer_classes = [JSONOpenAPIRenderer,]
2.视图组件之两个视图基类(*****
)
1.APIView
# 第一层:继承APIView完全自己写
class BookView(APIView):
def get(self, request):
qs = Book.objects.all()
ser = serializer.BookSerializer(instance=qs, many=True)
return Response(data=ser.data, status=200)
def post(self, request):
ser = serializer.BookSerializer(data=request.data)
if ser.is_valid():
ser.save()
return Response(data={'code': 100, 'msg': '创建成功'})
else:
return Response(data=ser.errors)
class BookDetailView(APIView):
def get(self, request, pk):
book = Book.objects.all().filter(pk=pk).first()
ser = serializer.BookSerializer(instance=book)
return Response(data=ser.data, status=200)
def put(self, request, pk):
book = Book.objects.all().filter(pk=pk).first()
ser = serializer.BookSerializer(data=request.data, instance=book)
if ser.is_valid():
ser.save()
return Response(data={'code': 100, 'msg': '修改成功'})
else:
return Response(data=ser.errors)
def delete(self, request, pk):
Book.objects.filter(pk=pk).delete()
return Response(data={'code': 100, 'msg': '删除成功'})
# models.py
class Book(models.Model):
name=models.CharField(max_length=32)
price=models.DecimalField(max_digits=5,decimal_places=2)
publish=models.CharField(max_length=32)
# ser.py
class BookSerializer(serializers.ModelSerializer):
class Meta:
model=Book
fields='__all__'
2.GenericAPIView
# 第二层:继承GenericAPIView Generic: adj. 通用的
from rest_framework.generics import GenericAPIView # 也是继承于APIView
1. 两个类属性
queryset = Book.objects.all() # 要序列化的数据对象( 可以不用.all(),内部get_queryset方法 自动.all() )
serializer_class = serializer.BookSerializer # 要使用的序列化类
2.三个方法
get_queryset() # 获取要序列化的多条数据对象
get_serializer() # 获取要使用的序列化类
get_object() # 获取要序列化的单条数据对象(查找条件:一定要用pk,如果你想改,重写类属性lookup_field)
class BookView(GenericAPIView):
queryset = Book.objects.all() # 要序列化的数据
serializer_class = serializer.BookSerializer # 要使用的序列化类
def get(self, request):
qs = self.get_queryset() # GenericAPIView提供的 等同于self.queryset
ser = self.get_serializer(instance=qs, many=True) # GenericAPIView提供的 等同于self.serializer_class
return Response(data=ser.data, status=200)
def post(self, request):
ser = self.get_serializer(data=request.data)
if ser.is_valid():
ser.save()
return Response(data={'code': 100, 'msg': '创建成功'})
else:
return Response(data=ser.errors)
class BookDetailView(GenericAPIView):
queryset = Book.objects.all()
serializer_class = serializer.BookSerializer
def get(self, request, *args, **kwargs):
book = self.get_object()
ser = self.get_serializer(instance=book)
return Response(data=ser.data, status=200)
def put(self, request, pk):
book = self.get_object()
ser = self.get_serializer(data=request.data, instance=book)
if ser.is_valid():
ser.save()
return Response(data={'code': 100, 'msg': '修改成功'})
else:
return Response(data=ser.errors)
def delete(self, request, pk):
self.get_object().delete()
return Response(data={'code': 100, 'msg': '删除成功'})
3.视图组件之5个视图扩展类(*****
)
# 第三层:继承GenericAPIView + 5个视图扩展类(不是视图类,没有继承APIView及其子类)
from rest_framework.mixins import ListModelMixin,CreateModelMixin,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin
from rest_framework.generics import GenericAPIView
class BookView(GenericAPIView,ListModelMixin,CreateModelMixin):
queryset = Book.objects.all()
serializer_class = serializer.BookSerializer
def get(self, request):
# qs = self.get_queryset()
# ser = self.get_serializer(instance=qs, many=True)
# return Response(data=ser.data, status=200)
return self.list(request)
def post(self, request):
return self.create(request)
class BookDetailView(GenericAPIView,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin):
queryset = Book.objects.all()
serializer_class = serializer.BookSerializer
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
# 小技巧:五个接口需要使用的方法名字 和 类名前面部分中 一一对应
1. 查所有 list
2. 增一个 create
3. 查一个 retrieve
4. 改一个 update
5. 删一次 destroy
4.视图组件之9个视图子类(*****
)
# 第4层:9个视图子类 # 实际开发,使用这种较多 因为还需要自己额外写一些业务逻辑,通常就是通过重写方法
# 分别是: 五个接口 + 其的组合
6. 查所有+增 ListCreate
7. 查一个+改 RetrieveUpdate
8. 查一个+删 RetrieveDestroy
9. 查一个+改+删 RetrieveUpdateDestroy
from rest_framework.generics import ListAPIView, CreateAPIView, ListCreateAPIView
from rest_framework.generics import RetrieveAPIView, UpdateAPIView, DestroyAPIView, RetrieveUpdateAPIView, \
RetrieveDestroyAPIView, RetrieveUpdateDestroyAPIView
# ListAPIView 就是继承 GenericAPIView + ListModelMixin
class BookView(ListCreateAPIView):
queryset = Book.objects.all()
serializer_class = serializer.BookSerializer
class BookDetailView(RetrieveUpdateDestroyAPIView):
queryset = Book.objects.all()
serializer_class = serializer.BookSerializer
5.视图组件之视图集(*****
)
5.1基本使用
# 第5层:继承视图集
from rest_framework.viewsets import ModelViewSet
class BookView(ModelViewSet):
queryset = Book.objects.all()
serializer_class = serializer.BookSerializer
# 继承ModelViewSet的路由写法: (路由必须指定 actions)
path('books/', views.BookView.as_view(actions={'get':'list','post':'create'})),
path('books/<int:pk>', views.BookView.as_view(actions={'get':'retrieve','put':'update','delete':'destroy'})),
5.2源码分析:ViewSetMixin类
# ViewSetMixin类 重写了as_view()
# 请求来了,路由匹配成功会执行 ViewSetMixin.as_view()内部里的view()
@classonlymethod
def as_view(cls, actions=None, **initkwargs):
def view(request, *args, **kwargs):
# 核心代码(所以路由中只要配置了对应关系,比如{'get':'list'}),当get请求来,就会执行list方法
for method, action in actions.items(): # method:get action:list
handler = getattr(self, action) # self就是视图类,去视图类中反射list
setattr(self, method, handler) # 通过反射往视图类中写入 self.get=list
return csrf_exempt(view)
# 作用:
使用ViewSetMixin类及其子类时,可在路由匹配时中,为 某个请求方式 指定 特定的视图接口
# 注意:1. 路由就必须指定actions参数 视图接口名就可以随意写,只要actions映射好就行
# 2. 使用ViewSetMixin类及其子类,一定要放在APIVIew前 (执行左继承的as_view)
# 例:指定 get请求 对应 get_all_book接口
# views.py
from rest_framework.viewsets import ViewSetMixin
class Book6View(ViewSetMixin,APIView):
def get_all_book(self,request):
print("xxxx")
book_list = Book.objects.all()
book_ser = BookSerializer(book_list, many=True)
return Response(book_ser.data)
# urls.py
path('books6/', views.Book6View.as_view(actions={'get': 'get_all_book'})),
5.3其他子类
-ViewSetMixin: 路由可指定actions参数 .as_view(actions={'get':'方法'})
-ViewSet: ViewSetMixin+APIView (作用:就是在基础的APIview上,可指定actions参数)
-GenericViewSet: ViewSetMixin+GenericAPIView (作用:就是在基础的Genericview上,可指定actions参数)
-ModelViewSet: ViewSetMixin+GenericAPIView+视图扩展类 (就是表五个接口都有)
-ReadOnlyModelViewSet:ViewSetMixin+GenericAPIView+ListModelMixin+RetrieveModelMixin (只读接口:查所有和查一个)
补充
1.在pycharm中查看类的继承关系
2.继承关系图
作业
# 作业一
1.两个视图基类
2.5个视图扩展类
3.9个视图子类
4.视图集的所有类
继承关系画出来,写出每个类中常用的方法和属性
# 作业二
-实现图书和和出版社的5个接口
-配置返回数据格式只能是json,只能解析json
# 作业三
1.什么是正向代理,什么是反向代理