zoukankan      html  css  js  c++  java
  • drf之apiview请求生命周期,渲染,序列化,orm回顾

    一、Django配置回顾

    """
    1)应用是否需要在INSTALLED_APPS中注册
        在没有使用到app的一些特殊操作时(比如数据库相关),可以不用注册,但是注册后,应用的所有功能都能使用
        结论:所有应用都可以完成注册
        
        
    2)数据库配置(全部在settings文件中完成即可)
    import pymysql
    pymysql.install_as_MySQLdb()
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': '数据库名',
            'USER': '账号',
            'PASSWORD': '密码',
            'HOST': '如果是127.0.0.1,该配置可以省略',
            "PORT": 3306,  # 如果是3306,该配置可以省略
        }
    }
    
    3)路由分发
    主路由:将应用自己逻辑相关的路由交给自己处理
    from django.conf.urls import url, include
    urlpatterns = [
        # ...
        url(r'^api/', include('api.urls')),    # /api/test/
    ]
    
    """

    二、orm配置回顾

    # models.py
    from django.db import models
    class User(models.Model):
        SEX_CHOICES = ((0, ''), (1, ''))
        name = models.CharField(max_length=64, verbose_name='姓名')
        age = models.IntegerField()
        height = models.DecimalField(max_digits=5, decimal_places=2, default=0)
        sex = models.IntegerField(choices=SEX_CHOICES, default=0)
        # sex = models.CharField(choices=[('0', '男'), ('1', '女')])
        icon = models.ImageField(upload_to='icon', default='icon/default.png')
        
        
    # settings.py
    # root就是将文件夹添加到 os.path 中
    MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
    # url就是配置路由 /路由名/
    MEDIA_URL = '/media/'
    from django.views.static import serve
    # 暴露文件给前端 主路由最下方 
    # url(r'^(?P<path>.*)$', serve, {'document_root': '/path/to/my/files/'})
    # https://;localhost:8000/media/icon/default.png # icon/default.png => path变量 {'document_root': '/path/to/my/files/'}文件的路径
    url(r'^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT})

     三、APIView请求生命周期

     1、重写的as_view方法

    """
    1)as_view方法完成路由配置,返回配置函数是 csrf_exempt(view),也就是禁用了csrf认证规则
    结论:所有继承APIView的子类,都不受csrf认证规则的限制
    
    2)将请求处理的任务交给dispath方法完成
    """

     2、重写的dispatch方法

    """
    完成了三大核心任务:
    1)请求对象的处理:请求渲染模块
    
    2)请求过程的处理:三大认证模块 => 自己代码完成处理
    
    3)请求结果的响应:异常模块处理异常响应 | 响应渲染模块处理正常响应
    """

    四、请求解析模块

    """
    1)二次封装了原生Django的wsgi协议的request对象,并做了向下兼容(原来request对象的内容,用现在的request对象都能访问)
    
    2)将所有拼接参数都放在request.query_params中,将所有数据包参数都放在request.data中
    
    3)路由的有名无名分组的数据还是保存在args和kwargs中
    """
    
    # 解析模块可以在settings.py自定义解析配置
    REST_FRAMEWORK = {
        # 解析模块
        'DEFAULT_PARSER_CLASSES': [
            'rest_framework.parsers.JSONParser',  # json
            'rest_framework.parsers.FormParser',  # urlencoded
            'rest_framework.parsers.MultiPartParser'  # form-data
        ],
        # 渲染模块
        'DEFAULT_RENDERER_CLASSES': [
            'rest_framework.renderers.JSONRenderer',
            'rest_framework.renderers.BrowsableAPIRenderer',  # 上线后会注释
        ],
    }

     - 向下兼容性

        def post(self, request, *args, **kwargs):
    
    
            # 向下兼容:原来对象拥有的,现在对象都有
            print(type(request))  # apiview二次封装的request  drf的
            print(type(request._request))  # 原来的request  django原生的wsgi

     五、响应渲染模块

    """
    1)当三大认证模块和自己处理请求的视图逻辑没有出现异常时,会执行响应渲染模块
    
    2)响应的数据会交给渲染模块来完成数据的渲染,渲染方式有两种:Json格式数据渲染、Brower格式数据渲染
    """
    # 渲染模块可以在settings.py自定义解析配置
    REST_FRAMEWORK = {
        # 渲染模块
        'DEFAULT_RENDERER_CLASSES': [
            'rest_framework.renderers.JSONRenderer',
            # 浏览器渲染,上线后会注释,不然浏览器请求接口就暴露了后台语言
            'rest_framework.renderers.BrowsableAPIRenderer',  
        ],
    }

     六、序列化组件

    1、单表序列化

    models.py

    from django.db import models
    from django.conf import settings
    
    # Create your models here.
    
    
    from django.conf import settings
    class User(models.Model):
        SEX_CHOICES = ((0, ''), (1, ''))
        name = models.CharField(max_length=64, verbose_name='姓名')
        password = models.CharField(max_length=64, verbose_name='密码')
        age = models.IntegerField()
        height = models.DecimalField(max_digits=5, decimal_places=2)
        sex = models.IntegerField(choices=SEX_CHOICES, default=0)
        # sex = models.CharField(choices=[('0', '男'), ('1', '女')])
        icon = models.ImageField(upload_to='icon', default='icon/default.png')
    
        # 自定义序列化给前台的字段
        # 1)可以格式化数据库原有字段的数据
        # 2)可以对外隐藏原有数据字段名
        # 3)可以直接链表
    
        # 制作插头
        @property
        def gender(self):
            return self.get_sex_display()  # get_sex_display()展示性别
    
    
        @property
        def img(self):
            # print(type(self.icon), self.icon)
    
            # res = settings.BASE_URL + settings.MEDIA_URL + str(self.icon)
            # 或者直接拿name也可以
            res = settings.BASE_URL + settings.MEDIA_URL + self.icon.name
            return res
    
        def __str__(self):
            return self.name

    serializers.py

    from rest_framework import serializers
    
    
    
    # 序列化
    from . import models
    class UserModelSerializer(serializers.ModelSerializer):
    
        # 配置类
        class Meta:
            # 自定义该序列化类是辅助于那个model类
            model = models.User
    
            # 设置参与序列化与反序列化字段
            # 插拔式:可以选择性返回给前端字段(插头都是在model类中制作)
            # fields = ['name', 'age', 'height', 'sex', 'icon', 'gender']
            fields = ['name', 'age', 'height', 'sex', 'img', 'gender']

    views.py

    from rest_framework.views import APIView
    from rest_framework.response import Response
    from . import models, serializers
    class UserAPIView(APIView):
        def get(self, request, *args, **kwargs):
            pk = kwargs.get('pk')
            if pk:
                # 单查
    
                # 1) 数据库交互拿到资源obj或资源objs
                # 2) 数据序列化成可以返回给前台的json数据
                # 3) 将json数据返回给前台
                obj = models.User.objects.get(pk=pk)
                serializer_obj = serializers.UserModelSerializer(obj)
                return Response(serializer_obj.data)
    
            else:
                # 群查
                # 1)数据库交互拿到资源obj或资源objs
                # 2)数据序列化成可以返回给前台的json数据
                # 3)将json数据返回给前台
                objs = models.User.objects.all()
                # 操作多个数据many=True
                serializer_obj = serializers.UserModelSerializer(objs, many=True)
                return Response(serializer_obj.data)
                
    
    
        def post(self, request, *args, **kwargs):
            # 单增
            # 1)从请求request中获取前台提交的数据
            # 2)将数据转换成model对象,并完成数据库入库操作
            # 3)将入库成功的对象序列化成可以返回给前台的json数据(请求与响应数据不对等:请求需要提交密码,响应一定不展示密码)
            # 4)将json数据返回给前台
    
            return Response()

  • 相关阅读:
    aws 计费查询
    关于网络抖动
    word2vec和onehot
    缺少了目标的教育是彻底的失败
    做事要风险控制
    SPS中计算值公式函数简介
    Moss + InfoPath 表单工作流开发要点
    【译】What is the NDK? (2)
    【译】What is the NDK? (1)
    【译】Android平台上的Flex开发(3) 在桌面和移动设备上测试
  • 原文地址:https://www.cnblogs.com/yafeng666/p/12326916.html
Copyright © 2011-2022 走看看