• DRF之源码分析(二)


    Django配置

    '''
    1.应用是否需要在INSTALLED_APPS中注册取决于是否使用到app的一些特殊操作(如数据库相关),可以不用注册,但是注册后,应用的功能都能使用。
    结论:所有应用都注册即可
    
    2.数据库配置:在settings.py中完成即可
    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.路由分发
    当项目比较庞大时,如果把所有路由匹配关系都写在总路由里,会比较难以管理和维护。所以我们可以将app相关的路由逻辑进行分发。
    urlpatterns = [
    	url(r'^api/',include('api.urls'))
    ]
    '''
    

    ORM配置回顾

    models.py

    from django.db import models
    class User(models.Model):
        pass
    
    

    APIView的请求生命周期

    1.APIView类继承了原生Django的View类,并重写了as_view方法
    """
    1)as_view方法完成路由配置,返回配置函数是 csrf_exempt(view),也就是禁用了csrf认证规则
    结论:所有继承APIView的子类,都不受csrf认证规则的限制
    
    2)将请求处理的任务交给dispath方法完成
    """
    
    2.重写的dispatch方法
    '''
    1.drf在self.initial_request中重新封装了request对象,并向下兼容了django的request属性。
    
    2.然后在self.initial中对request进行了用户、权限、吞吐量认证。
    
    3.利用反射,执行我们自己的视图类对request请求进行处理。
    
    4.在self.finalize_request中对response对象进行处理(如:渲染)
    
    5.最终返回response对象
    '''
    

    请求解析模块

    '''
    1.二次封装了原生django的wsgi协议的request对象,并做了向下兼容(原来request对象的内容,用封装过的request也可以访问)
    
    2.将所有拼接参数都放在request.query_params中,将所有数据包参数都放在request.data中
    
    3.路由的又名无名分组的数据还是保存在args和kwargs
    '''
    
    REST_FRAMEWORK = {
        # 解析类根据请求头中的 Content-Type
        'DEFAULT_PARSER_CLASSES': [
            # Content-Type: application/json
            'rest_framework.parsers.JSONParser',
            
            # Content-Type: application/x-www-form-urlencoded
            'rest_framework.parsers.FormParser',
            
            # Content-Type: multipart/form-data
            'rest_framework.parsers.MultiPartParser'
        ],
    }
    

    响应渲染模块

    '''
    1.当三大认证模块和自己处理请求的视图函数类没有出现异常时--源码中我们可以看到if isinstance(response, Response):
    
    2.响应的数据会交给渲染模块来完成数据的悬案,渲染方式有两种:Json格式数据渲染、Browser格式数据渲染
    '''
    REST_FRAMEWORK = {
        # 响应渲染类
        'DEFAULT_RENDERER_CLASSES': [
            'rest_framework.renderers.JSONRenderer',
            # 如果直接返回api.html会泄露源码 可对api.html进行修改或直接注释掉
            'rest_framework.renderers.BrowsableAPIRenderer',
        ],
    }
    
    

    序列化组件

    单表序列化

    models.py

    class User(models.Model):
        SEX_CHOICES = ((0,'男'),(1,'女'))
        name = models.CharField(max_length=64)
        age = models.IntegerField()
        height = models.DecimalField(max_digits=5,decimal_places=2,default=0)
        sex = models.IntegerField(choices=SEX_CHOICES,default=0)
        icon = models.ImageField(upload_to='icon',default='icon/default.png')
    
        def __str__(self):
            return self.name
    
        class Meta:
            verbose_name_plural = '用户表'
    
    serializers.py
    from rest_framework import serializers
    from . import models
    
    
    class UserModelSerializer(serializers.ModelSerializer):
        # 是为哪一个model类定制的序列化类
        class Meta:
            model = models.User
            # 设置参与序列化和反序列化的字段
            '''
            插拔式设计:
                在model的类中提前制作好“插头”
                外部选择性使用“插头”即可
            '''
            fields = ['name','age','height','sex','icon']
    
    views.py
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from rest_framework import settings
    from . import models
    from . import serializers
    
    
    class UserAPIView(APIView):
        def get(self, request, *args, **kwargs):
            pk = kwargs.get('pk')
            try:
                if pk:
                    obj = models.User.objects.get(pk=pk)
                    serializer = serializers.UserModelSerializer(obj, many=False)
                    print(serializer.data)
                    return Response(serializer.data)
                else:
                    objs = models.User.objects.all()
                    serializer = serializers.UserModelSerializer(objs, many=True)
                    print(serializer.data)
                    return Response(serializer.data)
            except:
                return Response({'status': 1, 'msg': '请求数据不存在'})
    
        def post(self, request, *args, **kwargs):
            print(request.data)
            return Response('post ok')
    
    

    附:源码分析

  • 相关阅读:
    鬼斧神工---计算机的开机启动过程
    微服务之日志落盘设计
    微服务架构设计
    一条SQL语句执行得很慢的原因有哪些?
    996:只要能活着就好,不管活得多么糟糕
    事务隔离性与隔离级别
    数据库悲观锁与乐观锁
    解决百度网盘(百度云)分享链接不存在失效、分享的文件已经被取消的问题
    宁撞金钟一下,不打破鼓三千,IT人要有志气,要进就进大的好的公司
    1430:家庭作业
  • 原文地址:https://www.cnblogs.com/Ghostant/p/12331718.html
Copyright © 2020-2023  润新知