内容详细
1 视图组件
# 9个视图子类---》是视图类
-CreateAPIView, ListAPIView, DestroyAPIView, RetrieveAPIView, UpdateAPIView
ListCreateAPIView, RetrieveUpdateAPIView, RetrieveUpdateDestroyAPIView, \
RetrieveDestroyAPIView
# 视图集
# ViewSet=APIView+ViewSetMixin
# GenericViewSet=GenericAPIView+ViewSetMixin
# 以后只要想自动生成路由,必须继承ViewSetMixin及其子类
# 之前的写法可以沿用,只是如果要自动生成路由可以选择继承ViewSet,GenericViewSet
from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet
from rest_framework.viewsets import ViewSet,GenericViewSet
from rest_framework.viewsets import ViewSetMixin
# 第四层:通过9个视图子类,编写视图函数
# from rest_framework.generics import CreateAPIView, ListAPIView, DestroyAPIView, RetrieveAPIView, UpdateAPIView
# from rest_framework.generics import ListCreateAPIView, RetrieveUpdateAPIView, RetrieveUpdateDestroyAPIView, \
# RetrieveDestroyAPIView
#
#
# # class PublishView(ListCreateAPIView): # 查询所有和新增接口就有了
# # class PublishView(CreateAPIView): # 新增接口就有了
# class PublishView(ListAPIView): # 查询所有接口就有了
# queryset = Publish.objects.all()
# serializer_class = PublishSerialzier
#
# # 有可能要重写--》get_queryset--》get_serializer_class--》perform_create--》get,post方法
#
#
# class PublishDetailView(RetrieveUpdateDestroyAPIView): # 查询单条,删除,修改
# # class PublishDetailView(RetrieveAPIView): # 查询单条
# # class PublishDetailView(DestroyAPIView): # 删除
# # class PublishDetailView(UpdateAPIView): # 修改
# # class PublishDetailView(RetrieveDestroyAPIView): # 查询单条和删除
# # class PublishDetailView(RetrieveUpdateAPIView): # 查询单条和更新
# # class PublishDetailView(UpdateAPIView,DestroyAPIView): # 更新和删除
# queryset = Publish.objects.all()
# serializer_class = PublishSerialzier
# 第五层:通过ViewSet写视图类
# 5个接口,都用一个视图类----》路由 有两个get
from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet
# ViewSet=APIView+ViewSetMixin
# GenericViewSet=GenericAPIView+ViewSetMixin
# 以后只要想自动生成路由,必须继承ViewSetMixin及其子类
# 之前的写法可以沿用,只是如果要自动生成路由可以选择继承ViewSet,GenericViewSet
from rest_framework.viewsets import ViewSet,GenericViewSet
from rest_framework.viewsets import ViewSetMixin
# 集成了5个视图扩展类+GenericViewSet(ViewSetMixin, generics.GenericAPIView)
# ViewSetMixin-->控制了路由写法变了
# class PublishView(ModelViewSet): # 修改路由,5个接口
class PublishView(ReadOnlyModelViewSet): # 修改路由,只读,查所有,查单个
queryset = Publish.objects.all()
serializer_class = PublishSerialzier
2 路由组件
# 只要继承ViewSetMixin 及其子类,路由写法就变了
# 视图类:继承ViewSetMixin,路由写法变了--->而且视图类中的方法不一定写成get,post..,可以随意命名,只不过定义路由时写法变成了path('test/', views.TestView.as_view({'get': 'login'})),get请求执行login方法
# 到底如何执行的?
# ViewSetMixin必须写在前面
ViewSetMixin--》as_view--->类的查找顺序---》actions就是传入的字典---》view闭包函数
def view(request, *args, **kwargs):
# get login
for method, action in actions.items():
# 把login方法的内存地址给了handler
handler = getattr(self, action)
# 通过反射,设置给get---》对应login---》get请求执行get方法,现在get方法变成了login方法
setattr(self, method, handler)
return self.dispatch(request, *args, **kwargs)# 跟之前一样了
# 视图类,继承ModelViewSet,路由写法
path('publish/', views.PublishView.as_view({'get':'list','post':'create'})),
path('publish/<int:pk>', views.PublishView.as_view({'get':'retrieve','put':'update','delete':'destroy'}))
# 到现在,咱们有了一种方式,可以在一个视图类中写很多方法,通过路由的配置,实现一个视图函数对应很多路由
# 上面的两个路由,可以自动生成--->生成上面那两条地址
第一步:导入drf提供的路由类
from rest_framework.routers import SimpleRouter
第二步:实例化得到对象
router = SimpleRouter()
第三步:注册路由
router.register('地址', 视图类, '别名')
router.register('publish', views.PublishView, 'publish')
第四步:在urlpatterns加入(两种方式)
path('/api/v1', include(router.urls))
urlpatterns+=router.urls
# SimpleRouter和DefaultRouter 用法完全一样,只是生成的路由不一样DefaultRouter比SimpleRouter多一条根地址,一般咱么就用SimpleRouter就可以
# 如果使用自动生成路由,必须继承谁及其子类?
GenericViewSet+5个视图扩展类至少之一---》才能自动生成
ModelViewSet
ReadOnlyModelViewSet
# action装饰器
-只要是继承ViewSetMixin视图类中方法,都可以加action装饰器,只要加了,自动生成路由会多生成--》127.0.0.1:8080/test/login:get或post都能触发
@action(methods=['GET','POST'],detail=False)
def login(self,request):
# 如果写法如下,生成的路径是127.0.0.1:8080/test/数字/login
@action(methods=['GET','POST'],detail=True)
def login(self,request):
# 以后路由写法有三种
path('books/<int:pk>', views.BookDetailView.as_view()),
# 继承了ViewSetMixin
path('publish/', views.PublishView.as_view({'get':'list','post':'create'}))
# 自动生成路由
from rest_framework.routers import SimpleRouter,DefaultRouter
router = SimpleRouter()
router.register('publish', views.PublishView, 'publish')
# 路由注册,两种方式
path('api/v1/', include(router.urls)),
urlpatterns+=router.urls
# 路由类,有连个SimpleRouter,DefaultRouter,DefaultRouter自动生成的路由更多
# action装饰器---》只要继承ViewSetMixin都能自动生成路由
# methods=请求方法,列表,
# detail=是否带id,
# url_path=地址如果不写,默认已方法名为地址,
# url_name=别名
# 写成如下,自动生成路由会生成一条路径:127.0.0.1:8080/test/login -->get,post都会触发
@action(methods=['GET','POST'],detail=True)
def login(self,request):
# 如果写法如下,生成的路径是127.0.0.1:8080/test/数字/login
@action(methods=['GET','POST'],detail=True)
def login(self,request):
# 通过action,怎么通过action判断,重写get_queryset,get_serializer_class