一 web开发模式

# 前后端混合开发(前后端不分离):通过模版语法,在服务器上处理好html的内容(组合字符串),返回给浏览器一堆字符串(字符串封装到respons对象里),浏览器在渲染

# 前后端分离:只专注于写后端接口,返回json、xml格式
# xml比json笨重 # 补充:什么是动态页面(需要查数据库的),什么是静态页面(内容写死的页面)
# 访问量大的home页面,进行静态页面优化

二 API接口

# 通过网络,规定了前后台信息交互规则的url链接,也就是前后台信息交互的媒介
Application Programming Interface

三 postman的使用

# postman是当前最好用的,模拟发送http请求的工具
# 解析json的网站
www.json.cn # 请求头中User-Agent:客户端的类型
# 请求头中加其他参数
# url的末尾加/,浏览器中不加,是因为两次get,重定向自动给加上去的

四 restfull规范

'''
1. 什么是RESTFUll     RESTfull 是目前最流行的 API 设计规范,用于 Web 数据接口的设计。     REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”     REST从资源的角度类审视整个网络,它将分布在网络中某个节点的资源通过URL进行标识,客户端应用通过URL来获取资源的表征,获得这些表征致使这些应用转变状态     所有的数据,不过是通过网络获取的还是操作(增删改查)的数据,都是资源,将一切数据视为资源是REST区别与其他架构风格的最本质属性
'''

十条规范

1 数据的安全保障
  • url链接一般都采用https协议进行传输

    注:采用https协议,可以提高数据交互过程中的安全性

抓包工具:fiddler,chales

2 接口特征表现
3 多数据版本共存

就比如手机app,有 些升级了,有些还没升级,没升级的,就是用的老版本

新升级的,用的新版本

4 数据即是资源,均使用名词(可复数)
5 资源操作由请求方式决定

6 过滤信息(filtering,或称查询参数)

  • 如果记录数量很多,服务器不可能都将它们返回给用户。API应该提供参数,过滤返回结果。下面是一些常见的参数。

https://api.baidu.com/v1/books?limit=10:指定返回记录的数量
https://api.baidu.com/v1/books?offset=10:指定返回记录的开始位置。
https://api.baidu.com/v1/books?page=2&per_page=100:指定第几页,以及每页的记录数。
https://api.baidu.com/v1/books?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。
https://api.baidu.com/v1/books?animal_type_id=1:指定筛选条件
7.响应状态码

7.1 正常响应

  • 响应状态码2xx

    • 200:常规请求

    • 201:创建成功

7.2 重定向响应

  • 响应状态码3xx

    • 301:永久重定向

    • 302:暂时重定向

7.3 客户端异常

  • 响应状态码4xx

    • 403:请求无权限

    • 404:请求路径不存在

    • 405:请求方法不存在

7.4 服务器异常

  • 响应状态码5xx

    • 500:服务器异常

8 错误处理,应返回错误信息,error当成key

发生错误时不要响应200状态码,有一种不恰当的做法是,即使发生错误,也返回200状态码,把错误信息放在数据体里面,就像下面这样。

{
"status": "failure",
"data": {
"error": "Expected at least two items in list."
}
}
9 返回结果,针对不同操作,服务器向用户返回的结果应该符合一下规范
GET /collection:返回资源对象的列表(数组),一般是[{"id":1,"name":"a",},{"id":2,name:"b"},]这种类型
GET /collection/resource:返回单个资源对象, 一般是查看的单条数据 {"id":1,"name":'a'}
POST /collection:返回新生成的资源对象 , 一般是返回新添加的数据信息, 格式一般是{}
PUT /collection/resource:返回完整的资源对象 一般时返回更新后的数据,{}
PATCH /collection/resource:返回完整的资源对象
DELETE /collection/resource:返回一个空文档 一般返回一个空字符串
10 Hypermedia API,提供链接

RESTful API最好做到Hypermedia,即返回结果中提供链接,API 的使用者未必知道,URL 是怎么设计的。

一个解决方法就是,在回应中,给出相关链接,便于下一步操作。

这样的话,用户只要记住一个 URL,就可以发现其他的 URL。

{
...
"feeds_url": "https://api.github.com/feeds",
"followers_url": "https://api.github.com/user/followers",
"following_url": "https://api.github.com/user/following{/target}",
"gists_url": "https://api.github.com/gists{/gist_id}",
"hub_url": "https://api.github.com/hub",
...
}

五 drf的安装和简单使用

# 安装:pip install djangorestframework=3.10.3
# 使用:
1 在settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config',
'rest_framework'
]
2 在models.py中写表模型
class Book(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5, decimal_places=2)
author = models.CharField(max_length=32)
3 新建一个序列化类
app01下建一个ser.py
from rest_framework.serializers import ModelSerializer
from app01.models import Book class BookModelSerializer(ModelSerializer):
class Meta:
model = Book
fields = "__all__"
4 在视图函数中写视图类,views.py
from rest_framework.viewsets import ModelViewSet
from app01.models import Book
from app01.ser import BookModelSerializer # Create your views here.
class BookViewSet(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookModelSerializer 5 写路由关系,urls.py
from app01 import views
from rest_framework.routers import DefaultRouter router = DefaultRouter() # 可以处理视图的路由器
router.register('book', views.BookViewSet) # 向路由中注册视图集 # 将路由中的所有路由信息追到django的路由列表中 urlpatterns = [
path('admin/', admin.site.urls),
] # 两个列表相加,就是将列表rooter.urls的值追加到urlpatterns,for循环,再.append
urlpatterns += router.urls

六 CBV源码

# ModelViewSet继承View(django原生View)
# APIView继承View # 先读View
# views.py
from django.views import View
class Books(View):
def get(self, request):
return HttpResponse('ok') # urls.py
path('books/', views.Books.as_view()),
'''
在这个地方应该写个函数的内存地址,views.Books.as_view()执行完,是个函数内存地址,Books继承了Views类,里面的as_view是类方法,所有由Books.as_view()
'''
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'] '''
因return view,view是as_view的闭包函数,Books.as_view()的调用,就是调用view,类的绑定方法,把类当对象传入。
'''
@classonlymethod
# 路由中,一般没有传参, **initkwargs没有值
def as_view(cls, **initkwargs):
def view(request, *args, **kwargs):
self = cls(**initkwargs) # 实例化,book对象
self.setup(request, *args, **kwargs)
return self.dispatch(request, *args, **kwargs)
# dispatch方法,先对象里找,没有去类中找,类中没有就去给类的父类找
return view def setup(self, request, *args, **kwargs):
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
# 传入的request,赋值给对象
self.request = request def dispatch(self, request, *args, **kwargs):
if request.method.lower() in self.http_method_names:
# 反射取值,得到get的内存地址
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
# 内存地址加括号并传参,就是传参调用函数
return handler(request, *args, **kwargs)

七 APIView源码

1 一切皆对象

函数也是对象

def foo(a,b):
return a+b foo.name = 'lq' # 一切皆对象 print(foo(2,3)) print(foo.name)  # lq’

2 局部禁用csrf

# 在视图函数上加装饰器@csrf_exempt
# csrf_exempt(view) 这么写和在视图函数上加装饰器是一模一样

3 源码

# urls.py
path('booksapiview/', views.BooksAPIView.as_view()) # views.py
from rest_framework.views import APIView
class BooksAPIView(APIView):
def get(self, request):
return HttpResponse('ok') # APIView的as_view方法(类的绑定方法)
@classmethod
def as_view(cls, **initkwargs):
# 调用父类,就是django的View类的as_view方法
view = super().as_view(**initkwargs)
# 把函数当对象,进行属性赋值
view.cls = cls
view.initkwargs = initkwargs
# Note: session based authentication is explicitly CSRF validated,
# 以后所有的请求,都没有csrf认证了,只要继承了APIView,就没有csrf的认证
# all other authentication is CSRF exempt.
# 就是给函数加装饰器@csrf_exempt
return csrf_exempt(view) # view = super().as_view(**initkwargs),--->django的View类中的as_view方法--->return self.dispatch(request, *args, **kwargs)--->回到APIView类的dispatch方法 # 类的方法调用,先从对象找--->产生对象的类中找--->父类--->父类的父类 def dispatch(self, request, *args, **kwargs):
self.args = args
self.kwargs = kwargs
# 重新包装成一个request对象,以后再用的request对象,就是新的request对象了,initialize_request,是Request类的一个实例化的返回
request = self.initialize_request(request, *args, **kwargs)
self.request = request
self.headers = self.default_response_headers # deprecate? try:
# 三大认证模块(request是新的request)
self.initial(request, *args, **kwargs) # Get the appropriate handler method
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)
# 渲染模块,根据客户端的不同(浏览器,postman),渲染不同的数据
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response

Request类的源码

# from rest-framework.request import Request
# 只要继承了APIView,视图类中的request对象,都是新,也就是上面新的self.initialize_request(request, *args, **kwargs)
# 原生的request在新的request._request class Request:
def __init__(self, request, parsers=None, authenticators=None,
negotiator=None, parser_context=None):
# 二次封装request,将原生request作为drf-request对象的_request属性
self._request = request
self.parsers = parsers or ()
self.authenticators = authenticators or ()
self.negotiator = negotiator or self._default_negotiator()
self.parser_context = parser_context
self._data = Empty
self._files = Empty
self._full_data = Empty
self._content_type = Empty
self._stream = Empty # 以后使用request对象,就像使用之前的request是一模一样(因为重写了__getattr__方法,request.methed用法是一样的,不用request._request.methed,request.属性的时,自动触发__getattr__方法
def __getattr__(self, attr):
try:
# 放射,从原生request对象中取属性方法
return getattr(self._request, attr)
except AttributeError:
# 改进,不仅可以点取属性,还可以用[]的形式取属性,类.__dict__
return self.__getattribute__(attr) # request.data 不是属性,是@property修饰的一个方法
# 还有返回的一个字典,post请求不管使用什么编码(urldecode、formdata、json),传过来的数据,都在request.data,
@property
def data(self):
if not _hasattr(self, '_full_data'):
self._load_data_and_files()
return self._full_data # GET方发虽然重写了,还是request.GET,
@property
def query_params(self):
return self._request.GET # 视图类中
print(request.query_params)
'''
也是GET过来的数据,作者给改了个名,认为query_params是查询集,
更符合drf规范,本来get过来的数据就是查询集
'''
print(request.GET)

drf(初始drf,restfull规范 ,CBV、APIView、Request源码)的更多相关文章

  1. DRF cbv源码分析 restful规范10条 drf:APIView的源码 Request的源码 postman的安装和使用

    CBV 执行流程 路由配置:url(r'^test/',views.Test.as_view()),  --> 根据路由匹配,一旦成功,会执行后面函数(request) --> 本质就是执 ...

  2. APIView源码与Request源码分析

    一.APIView源码分析 1.安装djangorestframework 2.使用 drf是基于cbv view的封装,所以必须写cbv ①第一步:写视图,必须写cbv 路由配置: from res ...

  3. Django day24 cbv和APIView的源码分析 和 resful的规范

    一:cbv的源码分析 1.CBV和FBV的区别: - Class Base View   CBV(基于类的视图) - Function Base View   FBV(基于函数的视图) 2.as_vi ...

  4. Django框架之drf:5、反序列化器校验部分源码分析、断言、drf之请求与响应、视图组件介绍及两个视图基类、代码部分实战

    Django框架之drf 目录 Django框架之drf 一.反序列化类校验部分源码解析 二.断言 三.drf之请求 1.Request能够解析的前端传入编码格式 2.Request类中的属性和方法 ...

  5. Flask快速入门day02(1、CBV使用及源码分析,2、模板用法,3、请求与响应的基本用法,4、session的使用及源码分析,5、闪现,6、请求扩展)

    目录 Flask框架 一.CBV分析 1.CBV编写视图类方法 二.CBV源码分析 1.CBV源码问题 2.补充问题 3.总结 三.模板 1.py文件 2.html页面 四.请求与响应 1.reque ...

  6. FBV和CBV的区别(源码分析)

    FBV和CBV源码分析 FBV直接调用user方法执行业务代码 CBV相当于在FBV上面封装了一层 from django.contrib import admin from django.urls ...

  7. 代码规范、GitHub提交源码的标准 答题人-杨宇杰

    1.格式与命名规范1.1 缩进 使用Tab缩进,而不是空格键1.2 换行 每行120字符 if,for,while语句只有单句时,如果该句可能引起阅读混淆,需要用" {"和&quo ...

  8. JAVAEE 是什么,如何获取各种规范jar包及各种规范的jar包源码

    1.什么是JAVA EE JAVA EE是由一系列规范组成的,规范是由JCP制定的,并且提供了参考实现.规范(Specification)是一系列接口,不包含具体实现 有以下常见的JAVA EE实现, ...

  9. 【DRF框架】restfull规范

    零:核心思想: 1.面对资源编程 2.根据HTTP请求方式的不同对资源进行不同的操作 一.协议 API与用户的通信协议,总是使用HTTPs协议. 二.域名 应该尽量将API部署在专用域名之下. htt ...

  10. django:CBV模式,源码解析

    非常好 DRF执行流程源码解析 https://www.cnblogs.com/suguangti/p/11120793.html https://www.cnblogs.com/haitaoli/p ...

随机推荐

  1. .NET Core开发实战(第18课:日志框架:聊聊记日志的最佳姿势)--学习笔记(下)

    18 | 日志框架:聊聊记日志的最佳姿势 除了使用 CreateLogger 指定 logger 的名称,实际上还可以借助容器来构造 logger,通常情况下我们会定义自己的类 namespace L ...

  2. linux 搭建http文件服务器

    1.安装httpd服务 yum -y install httpd 2.修改需要访问的文件路径 vi /etc/httpd/conf/httpd.conf ##默认是/var/www/html目录下的文 ...

  3. 【OpenGL ES】透视变换原理

    1 前言 ​ MVP矩阵变换 中主要介绍了模型变换(平移.旋转.对称.缩放)和观测变换基本原理,本文将介绍透视变换的基本原理. ​ 如下图,近平面和远平面间棱台称为视锥体,表示可见区域范围,视锥体以外 ...

  4. DOM和BOM的区别

    DOM和BOM的区别 在浏览器中运行的JavaScript可以认为由三部分组成:ECMAScript描述了该语言的语法和基本对象,DOM文档对象模型描述了处理网页内容的方法和接口,BOM浏览器对象模型 ...

  5. 深入理解Go语言(03):scheduler调度器 - 基本介绍

    一:什么是调度 平常我们在生活中会有哪些调度的例子呢?比如十字路口的红绿灯,它就是一种调度系统.在交通十字路口,每个路口上多多少少有一些车辆,为了限制这些车辆不随意行驶,就建起了红绿灯调度系统.红绿灯 ...

  6. channel管道

    channel 如果说goroutine是并发体的话,那么channels则是他们之间的通信机制.一个channel是一个通信机制,它可以让一个goroutine通过它给另一个goroutine发生值 ...

  7. Alpine安装gcc g++ make编译环境

    apk add gcc g++ make cmake gfortran libffi-dev openssl-dev libtool

  8. 基于java的图书管理系统

    基于java的图书管理系统 项目概述 使用数组存储数据实现一个图书管理系统,完成的功能有增加图书.删除图书.更新图书.查询图书.图书列表.增删改查 登陆注册 首页 图书更新 图书列表 开发工具/技术 ...

  9. 【系统设计】集团内部HR系统完结,项目从0到1总结

    最近一年学习了PMP,结合下PMP的知识,分享一下最近HR项目的全生命周期流程管理(需求分析.产品设计.系统开发.测试.上线.运营). 先一句话概括:战略分析-收集需求-流程梳理-关键需求-IT规划- ...

  10. 文心一言 VS 讯飞星火 VS chatgpt (203)-- 算法导论15.3 2题

    二.对一个16个元素的数组,画出2.3.1节中MERGE-SORT过程运行的递归调用树.解释备忘技术为什么对MERGE-SORT这种分治算法无效.需要写代码的时候,请用go语言. 文心一言,代码不完整 ...