一.昨日回顾
1 序列化类
-写一个类继承Serializer或者ModelSerializer
-写字段(很多字段类),很多字段属性
-视图类中:实例化得到一个对象:
-新增:data=字典
-修改:instance,data
-序列化:instance
-对象
-对象.data
-对象.errors
-对象.instance
2 source
-修改序列化后字典的key(字段名和source对应的名不能一样)
-执行函数(直接连表操作)
-可以.连表操作
3 SerializerMehtodField
-写在Serializer中
publish=serializers.SerializerMethodField()
def get_publish(self,obj):
-它不可以被反序列化
在Serializer中写两字段,一个作为序列化字段,一个作为反序列化字段
4 ModelSerializer(用的多)
-写一个类
-写一个内部类
class Meta:
model=表模型
fields='__all__'
fields-['id','name']
exclude=()
read_only_field=[]
extra_kwargs={'name':{'required':True}}
depth=1
-重写某些字段
-直接以fields中的 某个字段为字段名,继续写即可
-局部钩子,全局钩子
5 反序列化校验源码分析
6 many=True 源码分析
-__new__和__init__和__call__
-对象()触发该对象类的__call__
7 请求和响应
-Request对象
-data
-__getattr__
-Response对象
-data
-status
-headers
-通过配置实现前端只显示json格式
-在setting中全局配置
-在视图类中局部配
-drf有一套默认的配置文件,自己配置需要在settings.py中
REST_FRAMEWORK={}
二.今日内容
1. 2个视图类
①视图基类APIView
- 路径:rest_framework.views.APIView
- 继承==>原始View
- 重新封装成了drf的request对象
- 返回drf的Response对象
②通用视图类GenericAPIView
- 路径:rest_framework.generic.GenericAPIView
- 继承:APIView
- 主要属性:
-queryset:需要查询的模型对象集
-serializer_class:需要使用的序列化器类
控制序列化器的执行(检验,保存,转换数据)
控制数据库查询的执行
-queryset=models.Book.objects.all()
-serializer_class=serializer.BookModelSerializer
-get_queryset:获取配置的queryset
-get_object:路由中的分组字段必须是pk
-get_serializer:获取配置的序列化类
APIView:如果跟models没有关系(没有数据库相关操作),就继承它
GenericAPIView:有关数据库操作,queryset和serializer_class
代码演示
models.py
class Book(models.Model):
id = models.AutoField(primary_key=True)
title=models.CharField(max_length=32,null=True)
price=models.DecimalField(max_digits=5,decimal_places=2,null=True)
publish=models.CharField(max_length=32,null=True)
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('books/',views.BookAPIView.as_view()),
re_path('^books/(?P<pk>\d+)',views.BookDetailAPIView.as_view()),
path('books_ger/', views.BookGenericAPIView.as_view()),
re_path('^books_ger/(?P<pk>\d+)', views.BookDetailGenericAPIView.as_view()),
]
serializer.py
from app01 import models
from rest_framework import serializers
class BookModelSerializer(serializers.ModelSerializer):
class Meta:
model=models.Book
fields='__all__'
views.py
from app01 import models,serializer
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView
class BookAPIView(APIView):
def get(self,request):
book_list=models.Book.objects.all()
ser=serializer.BookModelSerializer(book_list,many=True)
return Response(ser.data)
def post(self,request):
ser=serializer.BookModelSerializer(data=request.data)
if ser.is_valid():
ser.save()
return Response('成功')
class BookDetailAPIView(APIView):
def get(self,request,pk):
book=models.Book.objects.get(id=pk)
ser=serializer.BookModelSerializer(book)
return Response(ser.data)
def put(self,request,pk):
book=models.Book.objects.get(id=pk)
ser=serializer.BookModelSerializer(book,data=request.data)
if ser.is_valid():
ser.save()
return Response('修改成功')
def delete(self,request,pk):
models.Book.objects.filter(id=pk).delete()
return Response('删除成功')
class BookGenericAPIView(GenericAPIView):
queryset = models.Book.objects.all()
serializer_class = serializer.BookModelSerializer
def get(self,request):
obj=self.get_queryset()
ser=self.get_serializer(obj,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('成功')
class BookDetailGenericAPIView(GenericAPIView):
queryset = models.Book.objects.all()
serializer_class = serializer.BookModelSerializer
def get(self,request,*args,**kwargs):
obj=self.get_object()
ser=self.get_serializer(obj)
return Response(ser.data)
def put(self,request,*args,**kwargs):
obj=self.get_object()
ser=self.get_serializer(obj,data=request.data)
if ser.is_valid():
ser.save()
return Response('修改成功')
def delete(self,request,*args,**kwargs):
self.queryset.filter(id=kwargs.get('pk')).delete()
return Response('删除成功')
2. 5个视图扩展类
CreateModelMixin:create方法创建一条
DestroyModelMixin:destory方法删除一条
ListModelMixin:list方法获取所有
RetrieveModelMixin:retrieve获取一条
UpdateModelMixin:update修改一条
自定义的两个视图扩展类
drf提供的5个视图扩展类
from rest_framework.mixins import ListModelMixin, CreateModelMixin, DestroyModelMixin, RetrieveModelMixin, \
UpdateModelMixin
3. 9个子类视图
CreateAPIView:继承CreateModelMixin,GenericAPIView,有post方法,新增数据
DestroyAPIView:继承DestoryModelMixin,GenericAPIView,有delete方法,删除数据
ListAPIView:继承ListModelMixin,GenericAPIView,有get方法获取所有
UpdateAPIView:继承UpdateModelMixin,GenericAPIView,有put和patch方法,修改数据
RetrieveAPIView:继承RetrieveModelMixin,GenericAPIView,有get方法,获取一条
ListCreateAPIView:继承ListModelMixin,CreateModelMixin,GenericAPIView,有get获取所有,post方法新增
RetrieveDestroyAPIView:继承RetrieveModelMixin,DestroyModelMixin,GenericAPIView,有get方法获取一条,delete方法删除
RetrieveUpdateAPIView:继承RetrieveModelMixin,UpdateModelMixin,GenericAPIView,有get获取一条,put,patch修改
RetrieveUpdateDestroyAPIView:继承RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,GenericAPIView,有get获取一条,put,patch修改,delete删除
自定义的视图子类
class CreateListGenericAPIView(GenericAPIView,CreateModelMixin,ListModelMixin):
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
class BookGenericAPIView(CreateListGenericAPIView):
queryset = models.Book.objects.all()
serializer_class = serializer.BookModelSerializer
drf提供的9个视图子类
4. 视图集
代码演示
urlpatterns = [
path('books_set/', views.BookSetView.as_view({'get':'list','post':'create'})),
path('books_set/', views.BookSetView.as_view()),
re_path('^books_set/(?P<pk>\d+)', views.BookSetView.as_view({'get':'retrieve','put':'update','delete':'destroy'})),
]
from rest_framework.viewsets import ModelViewSet
class BookSetView(ModelViewSet):
queryset = models.Book.objects.all()
serializer_class = serializer.BookModelSerializer
path('books_set/', views.BookSetView.as_view({'get':'list'})),
re_path('^books_set/(?P<pk>\d+)', views.BookSetView.as_view({'get':'retrieve'})),
from rest_framework.viewsets import ReadOnlyModelViewSet
class BookSetView(ReadOnlyModelViewSet):
queryset = models.Book.objects.all()
serializer_class = serializer.BookModelSerializer
5. action的使用
class BookView(ViewSet):
def lqz(self,request,*args,**kwargs):
print(self.action)
return Response('lqz')
代码演示
path('books_mix/', views.BookView.as_view({'get':'lqz'})),
path('books_mix2/', views.BookView.as_view({'get':'egon'})),
from rest_framework.viewsets import ViewSetMixin
class BookView(ViewSet):
def lqz(self,request,*args,**kwargs):
print(self.action)
return Response('lqz')
def egon(self,request,*args,**kwargs):
return Response('egon')
6. 路由的使用
from rest_framework import routers
router=router.SimpleRouter()
router.register('books',views.BookSetView)
-urlpatterns += router.urls
-re_path(r'v1/',include(router.urls))
-最原始的
-path('books/',views.BookAPIView.as_view()),
-ViewSetMixin的视图类
-path('books_set/',views.BookSetView.as_view({'get':'list','post':'create'}))
-ViewSetMixin的视图类
-自动生成,上面讲的
-当自动生成路由的时候,由于视图类中还有其他方法,是无法自动生成路由的
-加action装饰器:
-methods:什么请求方式会触发被装饰函数的执行
-detail:是True是基于带id的路由生成的,如果是False,是基于不带id的路由生成的
-@action(method=['get'],detail=True)
代码演示
from rest_framework import routers
router = routers.SimpleRouter()
router.register('books', views.BookSetView, basename='book')
router.register('publish', views.PublishSetView, basename='publish')
print(router.urls)
urlpatterns = [
path('admin/', admin.site.urls),
...
]
urlpatterns += router.urls
from rest_framework.decorators import action
class BookSetView(ModelViewSet):
queryset = models.Book.objects.all()
serializer_class = serializer.BookModelSerializer
@action(methods=['get'], detail=True)
def login(self,request,*args,**kwargs):
print(args)
print(kwargs)
print(self.action)
return Response('登录成功')
@action(methods=['post'], detail=False)
def lqz(self,request,*args,**kwargs):
return Response('lqz')
class PublishSetView(ModelViewSet):
queryset = models.Book.objects.all()
serializer_class = serializer.BookModelSerializer