温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

CVB:基于类的视图函数,resful规范,序列化

发布时间:2020-07-27 05:24:21 来源:网络 阅读:416 作者:fushuanglin 栏目:开发技术
-Class Base View(基于类的视图)
-Function Base View(基于函数的视图)
-def as_view 类方法
-def view:类方法内部,闭包函数定义:内层函数包含对外部作用域的引用
-python中一切皆对象:函数也是对象
-hasattr(self, 'get')--判断self类中是不是有该(get)方法  
-反射 setattr(self,get,get_all):相当于把get函数,变成了get_all 
-getattr(self, 'get'):拿到get函数的内存地址
- def view(request, *args, **kwargs):
    self = cls(**initkwargs)
    if hasattr(self, 'get') and not hasattr(self, 'head'):
        self.head = self.get
    self.request = request
    self.args = args
    self.kwargs = kwargs
    #执行:dispatch:谁的dispatch方法?写的cbv的那个c,视图中的那个视图类
    #我这个类如果没有写dispatch,会执行View中的dispatch方法
    return self.dispatch(request, *args, **kwargs)
-def dispatch(self, request, *args, **kwargs):
    #request.method 前台请求的方法,转成了小写
    #http_method_names View中定义的一个列表:是一堆请求方式
    if request.method.lower() in self.http_method_names:
        #getattr的第三个参数是默认值:self.http_method_not_allowed
        #拿到get方法的内存地址
        handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
    else:
        handler = self.http_method_not_allowed
    #get(request,*args, **kwargs)
    return handler(request, *args, **kwargs)

-总结:
-路由配置好,项目启动:as_view()---->返回结果是一个class View(object)内view函数的内存地址
-请求来了---->触发view函数的执行,就会执行dispatch方法---->根据请求的不同,分发到不同的视图函数执行,最终返回的是HttpResponse

1.1 阅读源码:
左侧工程栏--->设置图标-->点击--->show members(能看到py文件,类的方法)

2 resful规范(是什么)
-什么是resful(定义)
-是一个规范
-面向资源编程:把网络中所有东西,想象成资源
-规范:
-10条规范
-API与用户的通信协议,总是使用HTTPs协议:https比http安全
-域名
https://api.example.com 尽量将API部署在专用域名(会存在跨域问题)
https://example.org/api/ API很简单
例如写一个查询所有图书的api接口:https://api.example.com/books
https://127.0.0.1/api/books
-版本:每个接口都应该有版本
URL,如:https://api.example.com/v1/ https://127.0.0.1/api/v2/books(推荐用这种)
请求头 跨域时,引发发送多次请求
-路径,视网络上任何东西都是资源,均使用名词表示(可复数)
https://api.example.com/v1/books
https://api.example.com/v1/animals
https://api.example.com/v1/employees
不能这么写:
-获取所有图书:https://127.0.0.1/api/get_all_books
-新增一本书:https://127.0.0.1/api/add_book
同一都用这个:
https://api.example.com/v1/books
-method
GET :从服务器取出资源(一项或多项)
POST :在服务器新建一个资源
PUT :在服务器更新资源(客户端提供改变后的完整资源)
PATCH :在服务器更新资源(客户端提供改变的属性)
DELETE :从服务器删除资源
-过滤,通过在url上传参的形式传递搜索条件
https://api.example.com/v1/zoos?limit=10:指定返回记录的数量
-状态码
请求回去,需要有状态码
自定义状态码
status: 100表示成功
101表示用户名密码错误
102我也不知道什么错误
-错误处理,应返回错误信息,error当做key。
-{status:100,error:'错误信息写上'}
-返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范。
GET /books:返回资源对象的列表(数组)
GET /books/1:返回单个资源对象
POST /books:返回新生成的资源对象 -新增,传数据,一旦新增完成,把新的资源对象返回
PUT /books/1:返回完整的资源对象
PATCH /books/1:返回完整的资源对象
DELETE /books/1:返回一个空文档
-Hypermedia API,RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API 方法,使得用户不查文档,也知道下一步应该做什么。
{
status:100
msg:成功
url:127.0.0.1/books/1
}
核心:返回结果中提供链接

2.1 django写resful规范的接口
2.2 postman软件:模拟发请求的软件
2.3 格式化json格式数据
-https://www.json.cn/
2.4 put请求,django不会帮我解析body内的数据,需要自己处理

3 drf(django rest framework)框架(django的app)
安装:djangorestframework
-它是一个app,要在咱的项目中用
-只是快速的构建resful规范的接口
-csrf_exempt:局部禁用csrf(csrf是可以局部使用,局部禁用)
-以后再执行的dispatch方法是APIView的dispatch方法

resful的规范:****
-10 个
-1 推荐用https
-2 域名:
-3 版本:
-4 视网络上任何东西都是资源,均使用名词表示
-5 method通过请求的方式来表示是新增,获取,修改,删除资源
-6 过滤:(要查价格大于10的书)127.0.0.1/api/v1/books/?price_gt=10
-7 状态码:
-8 错误信息
-9 返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范。
-10 返回结果中提供链接

    APIView 类
    -继承了View
    -重写了as_view方法,在内部屏蔽了csrf
    -重写了dispatch方法---核心

        Request 类
    -封装了原来的request
    -request.data   --->前台传递过来的数据,放在里面
    -request重写了__getattr__方法
    -request.query_params   就是原来request.的GET

-getattr和setattr
-重点掌握这三点:
    -request.data 是个方法,包装成了属性,前台传过来body体中数据的数据,放在里面
    -request.query_params  这个是原来GET中的数据
    -request把原来的request包装进去了

4 APIView源码分析

5 序列化
-1 自己写for循环来处理(麻烦)
-2 django提供的序列化组件(不可控)
from django.core import serializers
ret=serializers.serialize('json','queryset对象')
ret就是序列化之后的字符串了,不需要再序列化了
-3 drf提供的序列化组件
-1 先导入
from rest_framework.serializers import Serializer
from rest_framework import serializers
-2 写一个类,继承Serializer
-3 在类内部写属性:
name=serializers.CharField()
-4 使用:
-先生成对象,需要传参数 instance:要序列化的对象(可能是queryset,也可能是单个对象)
many:如果是queryset---True,,如果是单个对象--False
-5 对象.data --->是一个字典

-1 重命名:用source:xx = serializers.CharField(source='name')
-2 取出出版社名字:
方式一:
-在模型表中重写str方法
-publish=serializers.CharField()
方式二:
-用source
-拿出出版社的城市
-publish=serializers.CharField(source='publish.city')

            *****如果不指定source,字段必须对应起来,如果指定了source,字段可以任意命名
        -source 可以指定字段,也可也指定方法
            publish.test这是个方法,会执行该方法,并拿到返回结果
            test = serializers.CharField(source='publish.test')
        -3 SerializerMethodField,可以指定一个方法
            publish=serializers.SerializerMethodField()

# 方法名:叫get_字段名,要传参数,参数是:当前book对象
def get_publish(self,obj):

obj 是当前book对象

                dic={'name':obj.publish.name,'email':obj.publish.email}
                return dic
            -方法内部可以继续用其他的序列化类
    -ModelSerializer
        -必须在类中写
        class Meta:
            model=指定表
    **      # fields = 'all'**
            # 指定只取这两个字段
            fields = ['nid','name']

** # 去掉指定的字段

exclude=['publish','authors']**

    **      # fields,跟exclude不能连用
            # 指定深度,就是跨几个表(官方建议小于10,我给你的建议小于3)
            # depth = 2**
向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI