zoukankan      html  css  js  c++  java
  • rest_framework中视图相关

    模型类的定义

    # 定义图书模型类BookInfo
    class BookInfo(models.Model):
        btitle = models.CharField(max_length=20, verbose_name='名称')
        bpub_date = models.DateField(verbose_name='发布日期')
        bread = models.IntegerField(default=0, verbose_name='阅读量')
        bcomment = models.IntegerField(default=0, verbose_name='评论量')
        is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')
    
        class Meta:
            db_table = 'tb_books'  # 指明数据库表名
            verbose_name = '图书'  # 在admin站点中显示的名称
            verbose_name_plural = verbose_name  # 显示的复数名称
    
        def __str__(self):
            """定义每个数据对象的显示信息"""
            return self.btitle

    定义一个序列化器

    from rest_framework import serializers  # 引入类
    
    class BookInfoSerializer(serializers.Serializer):
        """ 图书列表序列化器"""
        id = serializers.IntegerField(label="ID", read_only=True)
        btitle = serializers.CharField(label="名称", max_length=20)
        bpub_date = serializers.DateField(label='发布日期', required=False)
        bread = serializers.IntegerField(label='阅读量', required=False)
        bcomment = serializers.IntegerField(label='评论量', required=False)
        is_delete = serializers.BooleanField(label='逻辑删除', required=False)
        heroinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True)  # 新增
    
        def create(self, validated_data):
            """新建"""
            return BookInfo.objects.create(**validated_data)
    
        def update(self, instance, validated_data):
            """更新,instance为要更新的对象实例"""
            instance.btitle = validated_data.get('btitle', instance.btitle)
            instance.bpub_date = validated_data.get('bpub_date', instance.bpub_date)
            instance.bread = validated_data.get('bread', instance.bread)
            instance.bcomment = validated_data.get('bcomment', instance.bcomment)
            instance.save()
            return instance

    django本身的View类来构建一个RESTful风格的API接口的开发;

    import json
    from django.forms import model_to_dict
    from django.http import JsonResponse
    from django.shortcuts import HttpResponse
    from django.views import View
    from rest_framework.viewsets import ModelViewSet
    
    from .models import BookInfo
    
    
    class BooksAPIView(View):
        def get(self, request):
            """
            查询所有图书
            :param request:
            :return:
            """
            queryset = BookInfo.objects.all().values()
            book_list = []
            book_list = list(queryset)
    
            return JsonResponse(book_list, safe=False)
    
        def post(self, request):
            """
            新增图书
            :param request:
            :return:
            """
            json_bytes = request.body
            json_str = json_bytes.decode()
            book_dict = json.loads(json_str)
            book = BookInfo.objects.create(
                **book_dict
            )
    
            return JsonResponse({
                "id": book.id,
                "btitle": book.btitle,
                'bpub_date': book.bpub_date,
                'bread': book.bread,
                'bcomment': book.bcomment,
            }, status=201)
    
    
    class BookAPIView(View):
        """
        获取单个图书的信息
        """
    
        def get(self, request, pk):
            try:
                book = BookInfo.objects.get(id=pk)
            except Exception as e:
                print(e)
                return HttpResponse(status=404)
    
            book_dict = model_to_dict(book)
            return JsonResponse(book_dict)
    
        def put(self, request, pk):
            """
            修改图书信息
            :param request:
            :param pk:
            :return:
            """
            try:
                book = BookInfo.objects.get(id=pk)
            except Exception as e:
                print(e)
                return HttpResponse(status=404)
    
            # 校验参数
    
            json_bytes = request.body
            json_str = json_bytes.decode()
            book_dict = json.loads(json_str)
    
            BookInfo.objects.filter(id=pk).update(**book_dict)
            book_dict = model_to_dict(BookInfo.objects.get(id=pk))
            return JsonResponse(book_dict)
    
        def delete(self, request, pk):
            """
            删除
            :param request:
            :param pk:
            :return:
            """
            try:
                book = BookInfo.objects.get(id=pk)
            except Exception as e:
                print(e)
                return HttpResponse(status=404)
    
            book.delete()
            return HttpResponse(status=204)
    
    
    """
    urlpatterns = [
        url(r'^books/$', views.BooksAPIView.as_view()),
        url(r'^books/(?P<pk>d+)/$', views.BookDetailView.as_view()),
    ]
    """

    通过(from rest_framework.views import APIView)中的APIView类构建一个RESTful风格的API接口的开发;

    from .models import BookInfo
    
    from .serializers import BookInfoSerializer
    from rest_framework.views import APIView
    from rest_framework.response import Response
    
    
    class BooksAPIView(APIView):
        """
        与django中的view相比
        """
    
        def get(self, request):
            # 数据库中取数据;
            books = BookInfo.objects.all()
            # 序列化器的使用;
            serializer = BookInfoSerializer(books, many=True)
            # 返回数据
            return Response(serializer.data)
    
    
    """
    from app001 import views
    urlpatterns = [
        url(r'^books/$', views.BooksAPIView.as_view()),
    ]
    """
    
    """
    此时继承的APIView与django中的view比较;
    1,传入到视图方法中的是REST framework的Request对象,而不是Django的HttpRequeset对象;
    2,视图方法可以返回REST framework的Response对象,视图会为响应数据设置(render)符合前端要求的格式;
    3,任何APIException异常都会被捕获到,并且处理成合适的响应信息;
    4,在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制。
    """

    通过APIView的子类GenericAPIView子类构建一个RESTful风格的API接口的开发;

    from .models import BookInfo
    from .serializers import BookInfoSerializer
    from rest_framework.response import Response
    from rest_framework.generics import GenericAPIView
    
    
    class BooksAPIView(GenericAPIView):
        """
        与restframework中的APIView相比
        """
        # 取出queryset对象
        queryset = BookInfo.objects.all()
        # 定义一个序列化器的类
        serializer_class = BookInfoSerializer
    
        def get(self, request):
            # 数据库中取数据;
            qs = self.get_queryset()
            # 序列化器的使用;
            serializer = self.get_serializer(qs, many=True)
            # 返回数据
            return Response(serializer.data)
    
    
    class BookDetailView(GenericAPIView):
        # 取出queryset对象
        queryset = BookInfo.objects.all()
        # 定义一个序列化器的类
        serializer_class = BookInfoSerializer
    
        def get(self, request, pk):
            # 数据库中取数据;
            qs = self.get_object()
            # 序列化器的使用;
            serializer = self.get_serializer(qs)
            # 返回数据
            return Response(serializer.data)
    
    
    """
    from app001 import views
    urlpatterns = [
        url(r'^books/$', views.BooksAPIView.as_view()),
        url(r'^books/(?P<pk>d+)/$', views.BookDetailView.as_view()),
    ]
    """
    
    """
    获取多个对象时候使用的方法( qs = self.get_queryset())
    1,在这个视图中需要自己传入要返回的queryset对象;
    2,要传来做序列化的类;
    3,在定义的具体方法中来使用self.get_queryset()来获取类中的对象;
    4,获取序列化的类然后处理数据;
    5,将处理后的类返回到接口中;
    
    获取单个对象使用的方法(qs = self.get_object())
    步骤类似
    
    总结:
    在GenericAPIView的类中继承需要自己指定模型类;
    自己指定方法的映射关系;
    自己取对象;
    自己取序列化的类;
    自己返回数据
    """

    (from rest_framework.generics import GenericAPIView)(from rest_framework import mixins)通过这两个子类构建一个RESTful风格的API接口的开发;

    from .models import BookInfo
    from .serializers import BookInfoSerializer
    from rest_framework.generics import GenericAPIView
    from rest_framework import mixins
    
    
    class BooksAPIView(mixins.ListModelMixin, GenericAPIView):
        """
        与restframework中的APIView相比
        """
        # 取出queryset对象
        queryset = BookInfo.objects.all()
        # 定义一个序列化器的类
        serializer_class = BookInfoSerializer
    
        def get(self, request):
            return self.list(request)
    
    
    class BookDetailView(mixins.RetrieveModelMixin, GenericAPIView):
        # 取出queryset对象
        queryset = BookInfo.objects.all()
        # 定义一个序列化器的类
        serializer_class = BookInfoSerializer
    
        def get(self, request, pk):
            return self.retrieve(request)
    
    
    """
    from app001 import views
    urlpatterns = [
        url(r'^books/$', views.BooksAPIView.as_view()),
        url(r'^books/(?P<pk>d+)/$', views.BookDetailView.as_view()),
    ]
    """
    
    """
    总结:
    在mixins.RetrieveModelMixin与GenericAPIView相比较;
    1,封装(self.get_queryset()的方法;
    2,封装了self.paginate_queryset()的方法;
    3,封装了serializer = self.get_serializer(queryset, many=True)的方法;
    4,将序列化后的结果返回;
    """

    (from rest_framework.generics import ListAPIView)类构建一个RESTful风格的API接口的开发;

    from .models import BookInfo
    from .serializers import BookInfoSerializer
    from rest_framework.generics import ListAPIView
    
    
    class BooksAPIView(ListAPIView):
        # 取出queryset对象
        queryset = BookInfo.objects.all()
        # 定义一个序列化器的类
        serializer_class = BookInfoSerializer
    
    
    from rest_framework.generics import RetrieveAPIView
    
    
    class BookDetailView(RetrieveAPIView):
        # 取出queryset对象
        queryset = BookInfo.objects.all()
        # 定义一个序列化器的类
        serializer_class = BookInfoSerializer
    
    
    """
    from app001 import views
    urlpatterns = [
        url(r'^books/$', views.BooksAPIView.as_view()),
        url(r'^books/(?P<pk>d+)/$', views.BookDetailView.as_view()),
    ]
    """
    
    """
    总结:
    from rest_framework.generics import GenericAPIView
    from rest_framework import mixins
    等价与
    from rest_framework.generics import ListAPIView
    
    调用方式;
    在get的方法中指明要调用的类中的封装的方法;
    """

    (from rest_framework.viewsets import GenericViewSet)类构建一个RESTful风格的API接口的开发;

    from .models import BookInfo
    from .serializers import BookInfoSerializer
    from rest_framework import mixins
    from rest_framework.viewsets import GenericViewSet
    
    class BooksAPIViewSet(mixins.ListModelMixin,mixins.RetrieveModelMixin,GenericViewSet):
        """
        mixins.ListModelMixin:实现了list的函数;
       GenericViewSet(ViewSetMixin, generics.GenericAPIView):
            ViewSetMixin 重写了as_view的方法(在url中将请求方式和action对应    queryset,serializer_class两个参数);
            GenericAPIView(views.APIView) 实现了get_queryset()和get_object的方法:
        """
        # 取出queryset对象
        queryset = BookInfo.objects.all()
        # 定义一个序列化器的类
        serializer_class = BookInfoSerializer
    
    """
    url的访问形式
    urlpatterns = [
        url(r'^books/$', views.BooksAPIViewSet.as_view({"get": "list"})),
        url(r'^books/(?P<pk>d+)/$', views.BooksAPIViewSet.as_view({"get": "retrieve"})),
    ]
    """
    
    """
    总结:
    from rest_framework.generics import GenericAPIView
    from rest_framework import mixins
    等价与
    from rest_framework.generics import ListAPIView
    """

    action自定义方法扩张类构建一个RESTful风格的API接口的开发;

    from .models import BookInfo
    from .serializers import BookInfoSerializer
    from rest_framework.viewsets import ModelViewSet
    from rest_framework.decorators import action
    from rest_framework.response import Response
    
    
    class BookInfoViewSet(ModelViewSet):
        # 取出queryset对象
        queryset = BookInfo.objects.all()
        # 定义一个序列化器的类
        serializer_class = BookInfoSerializer
    
        # detail为False 表示不需要处理具体的BookInfo对象
        @action(methods=['get'], detail=False)
        def latest(self, request):
            """
            返回最新的图书信息
            """
            book = BookInfo.objects.latest('id')
            serializer = self.get_serializer(book)
            return Response(serializer.data)
    
        # detail为True,表示要处理具体与pk主键对应的BookInfo对象
        @action(methods=['put'], detail=True)
        def read(self, request, pk):
            """
            修改图书的阅读量数据
            """
            book = self.get_object()
            book.bread = request.data.get('read')
            book.save()
            serializer = self.get_serializer(book)
            return Response(serializer.data)
    
    
    """
    url的访问形式
    urlpatterns = [
        url(r'^books/$', views.BookInfoViewSet.as_view({'get': 'list'})),
        url(r'^books/latest/$', views.BookInfoViewSet.as_view({'get': 'latest'})),
        url(r'^books/(?P<pk>d+)/$', views.BookInfoViewSet.as_view({'get': 'retrieve'})),
        url(r'^books/(?P<pk>d+)/read/$', views.BookInfoViewSet.as_view({'put': 'read'})),
    ]
    """
    
    """
    总结:
    1) ViewSet
    继承自APIView,作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。
    
    在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法。
    
    2)GenericViewSet
    继承自GenericAPIView,作用也与GenericAPIVIew类似,提供了get_object、get_queryset等方法便于列表视图与详情信息视图的开发。
    
    3)ModelViewSet
    继承自GenericAPIVIew,同时包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。
    
    4)ReadOnlyModelViewSet
    继承自GenericAPIVIew,同时包括了ListModelMixin、RetrieveModelMixin。
    """



  • 相关阅读:
    Java子类与父类的初始化
    悠哈牛奶糖为什么有五种味道单独装的,而不是混合装的
    C++ TinyXml操作(含源码下载)
    动物园海洋馆
    冰上行走
    Tmux : GNU Screen 的替代品
    考虑使用jruby
    关于一些展现的框架
    python抓取google搜索url
    pythonwebkit
  • 原文地址:https://www.cnblogs.com/cerofang/p/9332807.html
Copyright © 2011-2022 走看看