zoukankan      html  css  js  c++  java
  • 视图家族案例

    视图家族案例

    一、models.py模型类

    from django.db import models
    class Student(models.Model):
        name = models.CharField(max_length=65)
        age = models.IntegerField(null=True)
    
    

    二、serializers自定义序列化类

    from rest_framework import serializers
    from . import models
    class StudentSerializers(serializers.ModelSerializer):
        class Meta:
            model = models.Student
    
            fields = ("name", "age")
    

    三、路由匹配

    from django.conf.urls import url
    from . import views
    
    urlpatterns = [
        # url(r'^admin/', admin.site.urls),
        # 第一个版本什么也没继承,就是原生的操作
        url(r'^v1/students/$', views.StudentAPIView.as_view()),
        url(r'^v1/students/(?P<pk>d+)/$', views.StudentAPIView.as_view()),
    
        # 第二版本继承了GenericAPIView类实现了群查
        url(r'^v2/students/$', views.StudentGenericAPIView.as_view()),
    
        url(r'^v2/students/(?P<pk>d+)/$', views.StudentGenericAPIView.as_view()),
    
        # 第三个版本继承了GenericAPIView类和工具类实现了群查
        url(r'^v3/students/$', views.StudentMixinGenericAPIView.as_view()),
    
        url(r'^v3/students/(?P<pk>d+)/$', views.StudentMixinGenericAPIView.as_view()),
    
        # 第四个版本工具视图类继承了rest_framework.generics具体实现的功能
        url(r'^v4/students/$', views.StudentMixinListAPIView.as_view()),
    
        url(r'^v4/students/(?P<id>d+)/$', views.StudentMixinListAPIView.as_view()),
    
        # 第五个版本工具视图集类继承了ModelViewSet实现了具有六大功能
        # 将所有请求方式与响应方法名,通过映射关系交给用户自己配置
        url(r'^v5/students/$', views.StudentModelViewSet.as_view(
            {
                "get": "list",
                "post": "my_post"
            }
        )),
    
        # 将所有请求方式与响应方法名,通过映射关系交给用户自己配置
        url(r'^v5/students/(?P<pk>d+)/$', views.StudentModelViewSet.as_view(
            {
                "get": "retrieve",
                "put": "update",
                "patch":"partial_update",
                "delete":"destroy"
            }
        )),
    
    ]
    
    

    四、视图类

    from . import models
    from .serializers import StudentSerializers
    from utilss.MyResponse import APIResponse
    # 视图家族
    from rest_framework import views, generics, mixins, viewsets
    """
    views: 视图类,
    mixins: 视图工具类
    generics: 工具视图类
    viewsets: 视图集
    """
    from rest_framework.views import APIView
    from rest_framework.generics import GenericAPIView
    # 两大视图类: APIView, GenericAPIView
    # 六大视图工具类
    from rest_framework.mixins import RetrieveModelMixin, 
        ListModelMixin, 
        CreateModelMixin, 
        UpdateModelMixin, 
        DestroyModelMixin
    
    """
    六大视图工具类:
        RetrieveModelMixin,  单查
        ListModelMixin,  群查
        CreateModelMixin, 单增
        UpdateModelMixin, 单更改,局部更改
        DestroyModelMixin 删除,自己写
    """
    from rest_framework import generics
    # 九大工具视图类:...
    from rest_framework import viewsets
    # 两大视图集基类:ViewSet、GenericViewSet
    # APIView继承Django的View
    """
    1.View 将请求方式与视图类的同名方法建立映射,完成请求响应
    2. APIView:
        view的功能:
        重写as_view禁用了csrf认证
        重写dispatch:请求、响应、渲染、异常、解析、三大认证
        多了一堆类属性,可以完成视图类的局部配置
        
    """
    from api02.serializers import StudentSerializers
    class StudentAPIView(APIView):
        def get(self, request, *args, **kwargs):
            student_list_obj = models.Student.objects.all()
            student_list = StudentSerializers(student_list_obj, many=True)
    
            return APIResponse(1, "data ok", results=student_list.data)
    
    # 3) GenericAPIView
    #  GenericAPIView 继承了APView类,具有他的全部功能
    # GenericAPIView提供了三个方法: get_object()、get_queryset()、get_serializer_class()
    """
     三个方法两个属性
     get_object(): 获取orm查询的类对象 ,Student object
     get_queryset(): orm对象数据中的结果集, models.Student.objects.all() <QuerySet [<Student: Student object>, <Student: Student object>]>
     get_serializer_class(): 获取序列化类,自定义的序列化类
     get_serializer(): 获取序列化类产生的结果
     这个几个方法都依赖于:
        queryset = models.Student.objects.all()
        serializer_class = StudentSerializers
    """
    
    class StudentGenericAPIView(GenericAPIView):
        """
        群查序列化
        1)
        student_list_obj = models.Student.objects.all()将这一句话转换了两句话,看源码
        设置类属性GenericAPIView中的queryset的值
        queryset = models.Student.objects.all()
        获取orm查询的对象结果
        stu_query = self.get_queryset()
        2)
        将一句话变成了两句话
        student_list = StudentSerializers(student_list_obj, many=True)
        设置自己序列的类
        serializer_class = StudentSerializers
        获取序列化类的结果
        stu_ser = self.get_serializer(stu_query, many=True),调用了get_serializer_class获取序列化的类
    
        把原先可以一步完成的事情分成了两部分
        """
        queryset = models.Student.objects.all()
        serializer_class = StudentSerializers
    
        def get(self, request, *args, **kwargs):
            print(self.get_object())
            print(self.get_queryset())
            print(self.get_serializer())
            print(self.get_serializer_class())
    
            stu_query = self.get_queryset()
            stu_ser = self.get_serializer(stu_query, many=True)
            return APIResponse(results=stu_ser.data)
    
    # 第三个版本
    from rest_framework import mixins
    
    """
    视图工具类mixins
    提供了群查,单增,单删等方法六大方法
    群查
    mixins.ListModelMixin
    """
    
    class StudentMixinGenericAPIView(mixins.ListModelMixin, mixins.CreateModelMixin, GenericAPIView):
        queryset = models.Student.objects.all()
        serializer_class = StudentSerializers
        # 群查
        def get(self, request, *args, **kwargs):
            return self.list(request, *args, **kwargs)
    
        # 单增
        def post(self, request, *args, **kwargs):
            return self.create(request, *args, **kwargs)
    
    # GenericViewSet第二大视图类
    # 与generics: 工具视图类
    from rest_framework.generics import CreateAPIView, ListAPIView, ListCreateAPIView, RetrieveAPIView, UpdateAPIView, 
        DestroyAPIView
    
    
    #  工具视图类六大功能              单增            群查
    class StudentMixinListAPIView(CreateAPIView, RetrieveAPIView, ListAPIView, UpdateAPIView, DestroyAPIView):
        """mixins.CreateModelMixin,
                        GenericAPIView
    
        都继承GenericAPIView视图类
        对用的功能列继承了对应工具mixins里面对应的类
        1. CreateAPIView 单增
        2. ListAPIView 群查
        3. ListCreateAPIView 群查和单增
        4 RetrieveAPIView 单增
        5 UpdateAPIView 单改 put/patch 提供了整体改和局部改,
        6 DestroyAPIView 单删一定要重写destroy方法因为他是将一条记录删除,所以要自己写字段删除功能
    
        单查和群查不能同时出现,因为都是get方法,只能同时访问一个
        """
        #           orm查询语句
        queryset = models.Student.objects.all()
        serializer_class = StudentSerializers
        # GenericAPIView中提供lookup_field 主要是为了url中单查,提供的不一定是主键,所以提供的是数据库中的唯一主键字段名就可以
        lookup_field = "id"
    
        # lookup_url_kwarg # 查找数据中的唯一键
    
        # 有删除需求的接口继承DestroyAPIView,重写destroy完成字段删除
        def destroy(self, request, *args, **kwargs):
            # 字段删除
            pass
    
    # 视图工具集
    from rest_framework.viewsets import ModelViewSet
    class StudentModelViewSet(ModelViewSet):
        """
        六大功能具有
        ViewSetMixin重写as_views()方法通过反射机制实现对应功能的请求
        as_views()完成了请求自定义映射,将所有请求方式与响应方法名,通过映射关系交给用户自己配置
        一般单查和群查共存使用继承 ReadOnlyModelViewSet类
    
        GenericViewSet类作为ReadOnlyModelViewSet的父类类作为ReadOnlyModelViewSet的父类,实现继承工具类中的单查和群查的方法
        ViewSet和GenericViewSet类的区别:登录接口post不需要增
        所以GenericViewSet标准的资源接口post请求一定会往数据库中增,ViewSet他是非资源接口post不需要数据库增数据的交互
        """
        queryset = models.Student.objects.all()
        serializer_class = StudentSerializers
    
        def my_post(self, request, *args, **kwargs):
            return APIResponse(1, "my post ok")
    
    # 实现登录接口
    class LoginAPIView(APIView):
        # post请求不会向数据库增加数据
        pass
    
    class LoginGenericAPIView(GenericAPIView):
        # 一定要添加这两句话,并且要post请求一定会将数据保存到数据中
        queryset = ''
        serializer_class = ''
    

    五、UpdateAPIView局部修改密码

    # 1.修改密码, 一定要以pk接收
    re_path(r'modify_pwd/(?P<pk>.*)$', views.ModifyPwdAPIView.as_view()),
    # 2. 重置密码序列化
    class ModifyPwdAPIView(UpdateAPIView):
        authentication_classes = [JSONWebTokenAuthentication]
        queryset = models.User.objects.all()
        serializer_class = serializers.ModifyPwdSerializer
    
    # 3.序列化类
    class ModifyPwdSerializer(serializers.ModelSerializer):
        code = serializers.CharField(max_length=10, write_only=True)
    
        class Meta:
            model = models.User
            fields = (
                'password',
                'phone',
                'code',
    
            )
    
        def validate(self, attrs):
            code = attrs.pop('code')
            phone = attrs.pop('phone')
            catch_code = cache.get(f"{settings.SMS_CACHE_KEY}{phone}")
            # 获取用户,底层已经给你封装了可以直接获取
            user_obj = self.context.get("request").user
    
            print(user_obj.phone)
            if phone != user_obj.phone:
                serializers.ValidationError({'phone': "手机号有误,请确认手机号"})
    
                # 判断两次密码是否一样
            elif code != catch_code:
            
                 raise serializers.ValidationError({"code": "验证码有误"})
            
             # 清除一次性验证码,使用过一次就不可以使用
             cache.set(f"{settings.SMS_CACHE_KEY}{phone}", "0000", 0)
    
            print(attrs)
            return attrs
    
       # User表必须重写update方法,才能操作密文密码
        def update(self, instance, validated_data):
            password = validated_data.get('password')
            instance.set_password(password) # 修改密码
            print(instance.password)
            return instance
    

    重写UpdateModelMixin类中update方法实现自定义返回数据

     def update(self, request, *args, **kwargs):
            partial = kwargs.pop('partial', False)
            instance = self.get_object()
            serializer = self.get_serializer(instance, data=request.data, partial=partial)
            serializer.is_valid(raise_exception=True)
            self.perform_update(serializer)
    
            if getattr(instance, '_prefetched_objects_cache', None):
                # If 'prefetch_related' has been applied to a queryset, we need to
                # forcibly invalidate the prefetch cache on the instance.
                instance._prefetched_objects_cache = {}
    
            return APIResponse(request=serializer.data)
    

    img

  • 相关阅读:
    PHP错误报告级别及调整方法
    使用微妙计算PHP脚本执行时间
    修改PHP的默认时区
    Rabbimq 安装过程,还有踩得坑!centos 安装
    "services "kubernetes-dashboard" not found"
    转载
    安装php rabbitmq扩展,继上一篇安装Rabbitmq
    php hash_file
    composer 安装
    php 朴韩屏
  • 原文地址:https://www.cnblogs.com/randysun/p/12292771.html
Copyright © 2011-2022 走看看