CBV源码分析 APIView的基本使用 APIView执行流程分析 Request对象源码分析 序列化类Serializer的使用 序列化常用字段和字段参数

概要

  • CBV源码分析

  • APIView的基本使用

  • APIView执行流程分析

  • Request对象源码分析

  • 序列化类Serializer的使用

  • 序列化类常用字段和字段参数

内容详细

# 1.知道看源码 能看懂流程 可以对你目前水平增长 可以在公司里顺利上手公司的项目
前期过程:比较难---不讲的源码--都要自己去看
要求:尽量逼着自己看懂流程----尽量慢的去理解---实在看不懂的,把老师讲的听懂了即可

# 2 一定要好好听,利用好,老师讲课的时间 争取课上消化  视频看再多遍,不如敲一遍代码

1.CBV源码分析

# 基于类的视图---》讲过了
必须要继承它:from django.views import View

# drf的东西 都是写cbv 必须要继承View

#######流程分析
# path('books/',views.BookView.as_view())
# 知道函数加括号执行优先级最高 所以会先得到views.BookViwe.as_view()的执行结果,是函数的内存地址------view这个函数的内存地址
过程:请求来了----路由匹配成功---会执行 这个函数---view(request)

 view----self.dispatch(request)
def view(request,*args,**kwargs):
    return self.dispatch(request,*args,**kwargs)

# dispatch---你是什么请求 就会执行视图类中请求名字的方法
def dispatch(self, request, *args, **kwargs):
    # 请求方法变成小写字符串,如果是get请求,就是'get'
    # self.http_method_names 列表['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
    if request.method.lower() in self.http_method_names:
    # 重点:反射,去对象中,根据字符串,取出方法或属性
    # 'get'===> self是视图类的对象===>handler就是你写在视图类中的get方法
     handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
   # 执行get方法====>视图函数的get方法
	 return handler(request, *args, **kwargs)

"""你是什么请求,就会执行视图类中请求名字的方法"""
  1. APIView的基本使用

# 前面分析了view的执行流程
# 如果使用了drf 以后写的都是cbv 但是都是继承drf提供的视图类,APIView
from rest_framework.views import APIView
# 以后写的cbv要继承 APIView 及其子类
"""两大坑需要特别注意
ps:
第一个坑:drf是个app,需要注册  ## 一定不要忘了注册 ##
INSTALLED_APPS = [
		...
    'rest_framework'   # 一定不要忘了注册
]
第二个坑:app01后面不加逗号 使用三引号加注释
 """

###补充:django项目中app的作用----django是一个大而全的框架---内置了很多app----帮我们完成了很多事儿---数据库迁移 多了很多的表 不是我们自己写的
INSTALLED_APPS = [
    'django.contrib.admin', # 后台管理,系统自带后台管理admin
    'django.contrib.auth', # 权限管理---生成6张表
    'django.contrib.contenttypes', # 对所有app表进行记录的
    'django.contrib.sessions', # session功能--django-session表---app
    'django.contrib.messages', # django消息框架---flask的闪现
   'django.contrib.staticfiles', # 静态资源
   'app01.apps.App01Config',
   'rest_framework', # 一定不要忘了注册
]
class BookViwe(APIView):
  def get(self,request):
    # return HttpResponse('hello web')  # 以后不要用django原生的响应了:四件套:render,HttpResponse,Response,JsonResponse
    return Response('hello web') # drf提供的响应----Response可以放字符串 字典 列表
它是HttpResponse+JsonResponse结合体

# 由于继承了APIView---执行APIView的as_view---执行APIView的dispatch---内部执行变化了

3.APIView执行流程分析

#### 流程分析
# path('books/', views.BookViwe.as_view())
# views.BookViwe.as_view()的执行结果,是函数内存地址===》view这个函数的内存地址
# 现在的as_view已经不是django原生View的as_view了===> 面向对象中 属性查找顺序(对象本身 所属类 所属父类)====>而是drf的APIView的as_view了

### 路由写法没变----执行发生了变化  ###
过程:请求来了---路由匹配成功----会执行 这个函数---view(request)

###派生方法:子类中重写父类中的方法或者新写方法叫派生
### 派生类===>子类
def as_view(cls, **initkwargs): # as_view是django的View的派生方法
    # 这个view就是原生django中View类的view,还是原来的view
    view = super().as_view(**initkwargs)
    # csrf_exempt--->去除了所有的csrf---》csrf中间件---》post提交数据,如果不注释---》协带csrf---》以后,无论中间件是否注释,都不需要带了
    # csrf_exempt装饰器装饰视图函数--->本质跟csrf_exempt(view)一模一样
    # 它就是装饰器的本质:把被装饰的函数当做参数 传入装饰器函数 返回值赋值给被装饰的函数
    return csrf_exempt(view)

"""重点:1 view还是原来的view,2 以后不用管csrf了"""

# dispatch---已经不是django原生View的dispatch了,是drf的APIView的dispatch了---查找顺序的问题
    def dispatch(self, request, *args, **kwargs):
				#1 包装了新的request对象--》以后视图类中用的request对象,就是新的request
        request = self.initialize_request(request, *args, **kwargs)

	try:  # 捕获了异常
       # 内部执行了三大认证:认证(登陆认证),频率(1分钟只能访问接口3次),权限(普通用户不能访问,超级用户才能访问) 
     self.initial(request, *args, **kwargs)
     # 原来dispatch的代码,重写了一下===>执行视图函数
     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) # 执行视图函数
            
    except Exception as exc:
        # 处理了异常 统一异常处理===>返回固定格式
         response = self.handle_exception(exc)
         # 装了response对象,响应对象,浏览器看到好看的样子,postman只看到json
         self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response
    
"""重点:
1.drf:包装了新的request对象(drf的Request的对象了),已经不是django的request对象了
	 # rest_framework.request.Request   以后新的request
	  # django.core.handlers.wsgi.WSGIRequest  django原来的
	  
2.在执行视图函数之前,执行了三大认证
3.处理了全局异常===> 执行三大认证期间 执行视图函数期间 如果出了错 都能统一处理
4.包装了响应对象"""

4.Request对象源码分析

# 以后视图类中使用的request对象,是rest_framework.request.Request的对象
# 源码
class Request:
    #1 把老的request放到了新的request的_request属性了
    # 新的request==> request._request  是老的
    __init__:    self._request = request(这个request是老的)
        
 # 2 以后新的request用起来跟原来一样用
# 取出原来老request的属性,以下方法取,麻烦 
    request._request.POST
    request._request.GET
    request._request.method
# 重写了__getattr__ 魔法方法,. 拦截  ===>对象.属性如果属性不存在,触发这个方法执行

# 新的request.POST,新的request中没有POST,触发Request类的__getattr__
def __getattr__(self, attr):
  try:
# 通过反射,去拿老request的属性或方法
return getattr(self._request, attr)
  except AttributeError:
    return self.__getattribute__(attr)

# 3 新的request有个data方法,包装成了数据属性
前端无论什么编码方式传得body体中的数据,都从request.data中取,当字典用即可
原生djagno,如果是formdata,urlencoded是从POST中取,如果是json,从body中取出来自己转

# 4 新的request有个query_params方法,包装成了数据属性
	就是原来老的request的GET属性
# 5 上传文件,跟之前一样用,但是人家重写了


# 新的request重点
1 老的request是新的request._request
2 跟原来一样用
3 body提交的数据都是从request.data中取
4 请求地址中的数据都从request.query_params中取



![](https://img2022.cnblogs.com/blog/2774169/202206/2774169-20220614173418725-1311138896.png)
![](https://img2022.cnblogs.com/blog/2774169/202206/2774169-20220614173428000-1130428096.png)


### 5.序列化类Serializer的使用

~~~python
# pycharm 中集成了 mysql,sqlite的客户端,可以直接使用pycharm连接myslq,sqlite
pycharm是用java写的--->能够连接myslq,下一个插件,其实是一个jar包—-->jdbc-java提供的连接数据库的接口,但是没有具体实现--->需要下不同的jar包,具体实现,再来连接mysql,sqllite

实在用不了
Navicat :收费软件,需要破解,it工作者,自己网上找破解

# 序列化组件--->一个类,可以完成下面的事
1. 序列化,把模型对象(book,queryset)转换成字典,经过drf的response以后变成json字符串
2. 反序列化,把客户端发送过来的数据(前端json格式字符串),经过request.data以后变成字典,序列化器可以把字典转成模型,存到数据库
3. 反序列化,完成数据校验功能---》前端传入的数据,长短,是否是邮箱,手机号....可以做校验

# 1 序列化的功能  表中数据,序列化后,以json格式返回给前端

5.2路由

path('books/', views.BookAPIView.as_view()),

5.3 视图类

from .models import Book
from .serializer import BookSerializer
class BookAPIView(APIView):
    def get(self,request):
        # 取出所有图书的qs对象
        books=Book.objects.all()
        # 借助于序列化类--》写一个序列化类
        # 类实例化时:instance:要序列化的对象   many:True 多条 先记着这两个参数
        
ser= BookSerializer(instance=books,many=True)
	# ser.data 完成了序列化
    print(ser.data)   # 把qs对象 转成了字典 根据序列化类中你写的字段转的
    return Response(ser.data)   
        

5.4序列化类

from rest_framework import serializers

class BookSerializer(serializers.Serializer):  # 一定要继承Serializer
    # 写要序列化的字段,比如,不想把作者给前端
    name = serializers.CharField()  # 字段类,跟models中一一对应
    price = serializers.IntegerField()  # 字段类,跟models中一一对应
    publish = serializers.CharField()  # 字段类,跟models中一一对应
    author = serializers.CharField()  # 字段类,跟models中一一对应

6.序列化类常用字段和字段参数

# 字段类和字段属性

### 字段类: 跟models一一对应 但是比它多
# # BooleanField 	
# NullBooleanField 	
# CharField 	
# EmailField
# RegexField 
# SlugField 
# URLField 	
# UUIDField 	
# IPAddressField 	
# IntegerField 	
# FloatField 
# DecimalField 
# DateTimeField 	
# DateField 	
# TimeField 	
# ChoiceField 	
# FileField 	
# ImageField 	

------ 以上都是models有的----下面是serializer独有的---
# ListField 	
# DictField 	



#### 字段属性--->写在字段类中的---》干啥用?反序列化校验用的!!!!
## 选项参数
# CharField
max_length 	最大长度
min_lenght 	最小长度
allow_blank 	是否允许为空
trim_whitespace 	是否截断空白字符

# IntegerField
max_value 	最小值
min_value 	最大值

# 通用参数:
### 重点讲
read_only 	表明该字段仅用于序列化输出,默认False
write_only 	表明该字段仅用于反序列化输入,默认False


required 	表明该字段在反序列化时必须输入,默认True
default 	反序列化时使用的默认值
allow_null 	表明该字段是否允许传入None,默认False
error_messages 	包含错误
编号与错误信息的字典

下列是比较常用的字段及字段属性

一、常见字段(经常使用到字段)
1、CharField

字符串字段(必须max_length 参数)

2、DateField  

日期类型 date(auto_now =True自动更新时间\auto_now_add默认创建时间)

3、DateTimeField

日期类型 datetime(同上)

4、IntegerField        整形

5、FloatField      浮点类型 double

6、TextField         字符串 longtext


二、比较常用的字段参数
1、null=True         数据库中字段是否可以为空

2、auto_now=True    自动创建---无论添加或修改,都是当前操作的时间

3.auto_now_add=True 自动创建---永远是创建时的时间

4、max_length=255      最大长度

5、default=""          默认值

7、unique=True         不允许重复


posted @   一颗平凡的小石头  阅读(59)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示