DRF视图/视图集
一.视图
首先要从路由开始,url(r'^books/$',views.BookView.as_view()),as_view是drf的指定写法,可看到返回Bookview的as_view方法。
1.views.py中继承APIView
- APIView继承django的view,将原本django中的HttpResponse对象封装成drf识别的Response对象,写法如下,需要自己手写get、post等方法
class BookView(APIView):
def get(self,request,*args,**kwargs):
print(kwargs,args,request.query_params)
pk = request.query_params.get("pk")
if not pk:
queryset_obj = models.Books.objects.all()
res = BookSerializer(instance=queryset_obj,many=True)
return Response(res.data)
else:
queryset_obj = models.Books.objects.filter(id=pk).first()
res = BookSerializer(instance=queryset_obj,many=False)
return Response(res.data)
def post(self,request,*args,**kwargs):
ser = BookSerializer(data=request.data)
addr = AddrSerializer(data=request.data)
if ser.is_valid() and addr.is_valid():
# ser.create(ser.validated_data,request.data.get("addr"))
addr_obj = addr.save(addr=request.data.get("addr"))
ser.save(addr=addr_obj)
return Response("添加成功!")
return Response(ser.errors)
2.views.py中继承GenericAPIView
- 先要知道GenericAPIView的作用,主要是对数据库对象和序列化对象做了封装,写法如下(queryset和seriallizer引用即可,还要重写get方法)
- 当获取单条数据url以参数形势传递 http://127.0.0.1:8001/books/?pk=1时,需要重写get_object()方法
class BookView(GenericAPIView):
queryset = models.Books.objects.all()
serializer_class = BookSerializer
def get(self,request,*args,**kwargs):
pk = request.query_params.get("pk")
if not pk:
res = BookSerializer(instance=self.queryset,many=True)
return Response(res.data)
else:
query_obj = self.get_object()
res = BookSerializer(instance=query_obj,many=False)
return Response(res.data)
def get_object(self):
pass
- 当获取单条数据url为http://127.0.0.1:8001/books/1/,urls.py中此时为url(r'^books/(?P
\d+)/$',views.BookView.as_view())
class BookView(GenericAPIView):
queryset = models.Books.objects.all()
serializer_class = BookSerializer
def get(self,request,*args,**kwargs):
print(kwargs,"kkkk")
# pk = request.query_params.get("pk")
pk = kwargs.get("pk")
if not pk:
res = BookSerializer(instance=self.queryset,many=True)
return Response(res.data)
else:
query_obj = self.get_object()
res = BookSerializer(instance=query_obj,many=False)
return Response(res.data)
3.继承ListAPIView、CreateAPIView等
- 如果继承了上述APIView,也就是在第2部分上又继承了mixins的一些方法,不用自己再写get、post等方法,下面两种方式相同
class BookView(GenericAPIView,mixins.ListModelMixin)
class BookView(ListAPIView)
二.视图集
视图集分为以下四种
class ViewSet(ViewSetMixin, views.APIView):
pass
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
pass
class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
mixins.ListModelMixin,
GenericViewSet):
pass
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
pass
urls.py需要定义成以下形式,此时获取单条或多条数据都会走list方法,
url(r'^books/$',views.BookView.as_view({"get":"list"})),
url(r'^books/(?P<pk>\d+)/$',views.BookView.as_view({"get":"list"}))
1.viewset
- viewset继承自ViewSetMixin和APIView,这个类中as_view重写,规定以动作actions来映射方法
- 需要自定义list等方法
views.py
from rest_framework.viewsets import ViewSet
class BookView(ViewSet):
def list(self,request,*args,**kwargs):
pk = kwargs.get("pk")
if pk:
queryset_obj = models.Books.objects.filter(pk=pk).first()
res = BookSerializer(instance=queryset_obj,many=False)
else:
queryset_obj = models.Books.objects.all()
res = BookSerializer(instance=queryset_obj,many=True)
return Response(res.data)
2.genericviewset
- 继承自GenericAPIView,是对数据库对象和序列化对象做了封装
view.py
class BookView(GenericViewSet):
queryset = models.Books.objects.all()
serializer_class = BookSerializer
def list(self,request,*args,**kwargs):
pk = kwargs.get("pk")
if pk:
obj = self.get_object()
serializer = self.serializer_class(obj)
else:
serializer = self.serializer_class(self.queryset, many=True)
return Response(serializer.data)
3.modelviewset
- modelviewset类似于ListAPIView、RetrieveAPIView等,自定义了create、list等方法,如果提供的方法满足自己的要求,可不重写,定义好路由、queryset、serializer_class等对象就行,不过很多时候都是自己写action对应方法,因为默认提供的不足以涵盖所有情况。
urls.py
url(r'^books/$',views.BookView.as_view({"get":"list"})),
url(r'^books/(?P<pk>\d+)/$',views.BookView.as_view({"get":"retrieve"}))
views.py
class BookView(ModelViewSet):
queryset = models.Books.objects.all()
serializer_class = BookSerializer
视图集: