ModelModelSerializer和视图

Posted zgf-666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ModelModelSerializer和视图相关的知识,希望对你有一定的参考价值。

ModelModelSerializer

ModelModelSerializer和ModelForm组件很相似

1.自当义类继承ModelSerializer

from rest_framework.serializers import ModelSerializer
class BookModelSerializers(ModelSerializer):
   class Meta:
       model=models.Book
       fields="__all__"

2.处理get请求:

url(r‘^book/$‘, views.BookView.as_view())
from rest_framework.views import APIView
from rest_framework.response import Response
class BookView(APIView):
    def get(self, request):
        book_list = models.Book.objects.all()
        bs = BookModelSerializers(book_list, many=True)
        return Response(bs.data)  # 序列化接口,将bs的所有内容都返回
#在处理get请求时只是将BookSerializers换为BookModelSerializers

3.处理post请求:

 def post(self,request):
        bs=BookModelSerializers(data=request.data,)
        if bs.is_valid():# 校验字段接口
            bs.save() #创建记录接口create
            return Response(bs.data)  # 序列化接口
        return Response(bs.errors)  # 序列化接口
接受到数据就,进行校验,如果合格,就存起来(save),否则就将错误显示出来

4.处理查看指定个数据,编辑和删除请求:

 url(r‘^book/(d+)/$‘, views.BookDetailView.as_view())
class BookDetailView(APIView):
    def get(self,request,pk):
        #对单个对象进行序列化
        book=models.Book.objects.filter(pk=pk).first()
        bs=BookModelSerializers(book)  #序列化具体的对象
        return Response(bs.data)
    def put(self,request,pk):
        book = models.Book.objects.filter(pk=pk).first()
        bs=BookModelSerializers(data=request.data,instance=book)
        if bs.is_valid():
            bs.save()
            return Response(bs.data)
        else:return Response(bs.errors)
    def delete(self, request,pk):
       models.Book.objects.filter(pk=pk).first().delete()
       #如果删除就返回空
       return Response()

       编写视图     

使用ModelModelSerializer自定义编写视图
url
 url(r^book/$, views.BookView.as_view()),
 url(r^book/(d+)/$, views.BookDetailView.as_view()),
views.py
from rest_framework.serializers import ModelSerializer
class BookModelSerializers(ModelSerializer):
   class Meta:
       model=models.Book
       fields="__all__"
      
技术分享图片
from rest_framework.views import APIView
from rest_framework.response import Response
class BookView(APIView):
    def get(self,request):
        book_list=models.Book.objects.all()
         bs=BookModelSerializers(book_list,many=True)
        return Response(bs.data) # 序列化接口,将bs的所有内容都返回
    def post(self,request):
        print("request.data", request.data)
        bs=BookModelSerializers(data=request.data,)
        if bs.is_valid():# 校验字段接口
            bs.save() #创建记录接口create
            return Response(bs.data)  # 序列化接口
        return Response(bs.errors)  # 序列化接口
BookView
技术分享图片
class BookDetailView(APIView):
    def get(self,request,pk):
        #对单个对象进行序列化
        book=models.Book.objects.filter(pk=pk).first()
        bs=BookModelSerializers(book)
        return Response(bs.data)
    def put(self,request,pk):
        book = models.Book.objects.filter(pk=pk).first()
        ###bs为序列化对象
        bs=BookModelSerializers(data=request.data,instance=book)
        if bs.is_valid():
            bs.save()
            return Response(bs.data)
        else:return Response(bs.errors)
    def delete(self, request,pk):
       models.Book.objects.filter(pk=pk).first().delete()
       #如果删除就返回空
       return Response()
BookDetailView

使用混合(mixins)

url(r^publish/$, views.PublishView.as_view()),
url(r^publish/(?P<pk>d+)/$, views.PublishDetailView.as_view()),
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.serializers import ModelSerializer
from rest_framework import mixins
from rest_framework import generics
class PublishModelSerializer(ModelSerializer):
    class Meta:
        model=models.Publish
        fields="__all__"

技术分享图片
class PublishView(mixins.ListModelMixin,mixins.CreateModelMixin,generics.GenericAPIView):
    queryset = models.Publish.objects.all()
    serializer_class = PublishModelSerializer
    def get(self,request, *args, **kwargs):
        return self.list(request, *args, **kwargs)
    def post(self,request, *args, **kwargs):
        return self.create(request, *args, **kwargs)
PublishView
技术分享图片
class PublishDetailView(mixins.DestroyModelMixin,mixins.RetrieveModelMixin,mixins.UpdateModelMixin,generics.GenericAPIView):
    queryset = models.Publish.objects.all()
    serializer_class = PublishModelSerializer
    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)
PublishDetailView

使用通用的基于类的视图

url(r^authors/$, views.AuthorsView.as_view()),
url(r^authors/(?P<pk>d+)/$, views.AuthorsDetailView.as_view()),
class AuthorModelSerializers(ModelSerializer):
    class Meta:
        model=models.Author
        fields="__all__"
class AuthorsView(generics.ListCreateAPIView):
    queryset = Author.objects.all()
    serializer_class = AuthorModelSerializers
class AuthorsDetailView(generics.RetrieveUpdateDestroyAPIView):
    queryset = Author.objects.all()
    serializer_class = AuthorModelSerializers

viewsets.ModelViewSet

url

 

 url(r^authors/$, views.AuthorsModelView.as_view({"get": "list", "post": "create"}),),
    url(r^authors/(?P<pk>d+)/$, views.AuthorsModelView.as_view({
        get: retrieve,
        put: update,
        delete: destroy
    }),

 

views
from rest_framework.viewsets import  ModelViewSet
from app01 import models
class AuthorsModelView(ModelViewSet):
    queryset = models.Author.objects.all()
    serializer_class = AuthorModelSerializers
使用viewsets.ModelViewSet方法便捷高效,具体流程:
1.django启动
Djago启动过后 views.AuthorsModelView.as_view({"get": "list", "post": "create"})
和views.AuthorsModelView.as_view({
‘get‘: ‘retrieve‘,
‘put‘: ‘update‘,
‘delete‘: ‘destroy‘
})都会被执行,找AuthorsModelView中的as_view方法,无此方法,去父类ModelViewSet查找
2.ModelViewSet源码:
class ModelViewSet(mixins.CreateModelMixin,
                   mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   GenericViewSet):  pass
ModelViewSet中无s_view方法,去父类中查找
  CreateModelMixin中放着新建数据的函数
  RetrieveModelMixin中放着查看某条数据的函数
  UpdateModelMixin中放着更新数据的函数
  DestroyModelMixin中放着删除数据的函数
  ListModelMixin中放着展示全部数据的函数
  去GenericViewSet中查找as_view方法
3.执行ViewSetMixin中的as_view
GenericViewSet源码:
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):pass
GenericViewSet中无as_view方法,向其父类中查找
执行ViewSetMixin中的as_view。ViewSetMixin源码:

class ViewSetMixin(object):
     def as_view(cls, actions=None, **initkwargs):
         def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            self.action_map = actions
             for method, action in actions.items():
                handler = getattr(self, action)
                setattr(self, method, handler)
            if hasattr(self, get) and not hasattr(self, head):
                self.head = self.get
            self.request = request
            self.args = args
            self.kwargs = kwargs
            return self.dispatch(request, *args, **kwargs)
     return csrf_exempt(view)
找到as_view方法后,执行此方法返回view
url(r^authors/$, views.AuthorsModelView.as_view({"get": "list", "post": "create"}), ),
url(r^authors/(?P<pk>d+)/$, views.AuthorsModelView.as_view({
    get: retrieve,
    put: update,
    delete: destroy
}),
相当于:
url(r^authors/$, view),
url(r^authors/(?P<pk>d+)/$, view)
这是启动django后就完成的工作,当用户发送请求时,view执行
4.发送请求,执行ViewSetMixin中的view方法
def view(request, *args, **kwargs):
    self = cls(**initkwargs)
    for method, action in actions.items():
        handler = getattr(self, action)
        setattr(self, method, handler)
    return self.dispatch(request, *args, **kwargs)

最终的返回值时执行dispatch函数,在着之前的for循环的作用?
需要知道actions是什么,但是函数中并没有actions这个值,在这里使用了闭包

class ViewSetMixin(object):
     def as_view(cls, actions=None, **initkwargs):
         def view(request, *args, **kwargs):
             for method, action in actions.items():pass
在django启动时,执行as_view时传的有参数,
views.AuthorsModelView.as_view({"get": "list", "post": "create"})
在执行as_view时,默认参数actions接收到了{"get": "list", "post": "create"},在执行view时,使用这些值,不同的url执行actions接收值不同,
在执行view时也不同
for method, action in actions.items():
    handler = getattr(self, action)
    setattr(self, method, handler)
method的值就是"get","post",action为"list","create"
handeler的值为self.list/self.create
setattr重新赋值,如setattr(self, "get",self.list)等同于再进行getattr(self,"get")

5.执行self.dispatch,执行APIView中的dispatch

 

AuthorsModelView,ModelViewSet,GenericViewSet,GenericAPIView
均无dispatch方法,在APIView中有dispatch方法
class APIView(View):
  def dispatch(self, request, *args, **kwargs):
     request = self.initialize_request(request, *args, **kwargs)
     self.request = request
      if request.method.lower() in self.http_method_names:
          handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
      else:
         handler = self.http_method_not_allowed
      response = handler(request, *args, **kwargs)
      return self.response
执行APIView中的dispatch方法:
handler = getattr(self, request.method.lower(),self.http_method_not_allowed)
执行反射时,如果发来的请求get,此时handler不再是self.get,而是self.list.是因为在执行ViewSetMixin中的view方法时
setattr(self, method, handler)重新赋值了
执行handler函数,response=self.list(request, *args, **kwargs),去AuthorsModelView中list方法
class ListModelMixin(object):
    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)
handler执行后的结果返回给response,dispatch函数将response返回给view,view在页面上显示出来









































以上是关于ModelModelSerializer和视图的主要内容,如果未能解决你的问题,请参考以下文章

View(视图)——ListView之BaseAdapter和SimpleCursorAdapter以及网格视图代码视图

在视图代码类文件中引用超级视图

快捷方式代码(根据数量隐藏视图)

如何在 Rails 视图中注释代码?

asp.net mvc 视图和强类型视图数据

保存和检索图像和标签到下一个视图。代码