@
目录(三十六)Web应用模式
在Web开发中,有两种模式:
- 前后端分离
#前后端分离: 只专注于后端,返回json格式数据
- 前后端不分离
# 前后端混合开发(前后端不分离) 返回的是HTML的内容,需要写模板
# 动态页面(查数据库),静态页面(一个静止的html)
# 页面静态化
(三十七)API接口
通过网络,规定了前后端信息交互的url连接,也就是前后端信息交互的媒介
(三十八)Restful规范
REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征性状态转移)。它首次出现在2000年Roy Fielding的博士论文中
RESTFUL是一种定义Web API接口的设计风格,尤其适合前后端分离的应用模式中。
这种风格的理念认为后端开发任务就是提供数据的,对外提供的是数据资源访问的接口,所以在定义接口时,客户端访问的URL路径就表示这种需要操作的数据资源
事实上,我们可以使用任何一种框架都可以实现符合RESTFUL规范的API接口
- 数据的安全保障
url链接一般都采用https协议进行传输,注:采用Https协议,可以提高数据 交互过程中的安全性
- 接口的特征表现
-用api关键字标识接口url:
-[https://api.baidu.com](https://api.baidu.com/)
-https://www.baidu.com/api
注:看到api字段,就代表该请求url链接是完成前后端数据交互的
- 多版本共存
-在url链接中标识数据版本
-https://api.baidu.com/v1
-https://api.baidu.com/v2
注:url链接中的v1,v2,就是不同数据版本的提现,(只有在一种数据资源有多版本情况下)
- 数据即资源
接口作为前后端交互的媒介其交互的数据又被叫做资源,推荐使用名词或者名词的复数形式,对于某些特殊接口,我们可以使用动词(api/books api/login)
- 接口一般都是前后端数据的交互,交互的数据称之为资源
- https://api.baidu.com/users
- https://api.baidu.com/books
- **资源操作由请求方式决定 ** (method)
资源的操作我们直接通过提交的请求方式来决定(get、post、put/patch、delete)
- 操作资源一般都涉及到增删改查,以下请求方式来标识增删改查动作
https://api.baidu.com/books -get请求:获取所有书
https://api.baidu.com/books/1 -get请求:获取主键为1 的书
https://api.baidu.com/books -post请求: 新增一本书
https://api.baidu.com/books/1 -put请求:整体修改主键为1的书
https://api.baidu.com/books/1 -patch请求:局部修改主键为1 的书
https://api.baidu.com/books/1 -delete请求:删除主键为1 的书
- 过滤
我们可以再url上传参的形式传递搜索条件
https://api.example.com/v1/people?limit=10 :指定返回记录的数量
https://api.example.com/v1/people?offset=10 :指定返回记录的开始位置
https://api.example.com/v1/people?page=2&per_page=100 :指定第几页,以及每页的记录数
https://api.example.com/v1/people?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序
https://api.example.com/v1/people?animal_type_id=1 :指定筛选条件
- 响应状态码
# 正常响应
200(正常请求)、
201(创建成功)、
# 重定向响应
301(永久重定向)、
302(临时重定向)、
# 客户端异常
403(请求无权限)、
404(请求路径不存在)、
405(请求方法不存在)、
# 服务端异常
500(服务器异常)、
- 错误处理
应当返回错误信息 error当作key
{
error:'无权限操作'
}
- 返回结果
根据不同的请求以及请求得到的数据, 服务端返回不同的结果
GET /collection:返回资源对象的列表(数组)
GET /collection/resource:返回单个资源对象
POST /collection:返回新生成的资源对象
PUT /collection/resource:返回完整的资源对象
PATCH /collection/resource:返回完成的资源对象
DELETE /collection/resource:返回一个空文档
- 需要url请求的资源需要访问资源的请求链接
# Hypermedia API ,RESTFUL API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么
{
"status":0,
"msg":"OK",
"results":[
{
"name":"肯德基",
"img":"https://image.baidu.com/ftc/001.png"
}
........
]
}
(三十九)drf安装和简单使用
1、安装
#安装
pip install djangorestframework
2、使用
1.settings.py中
INSTALLED_APPS = [
'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=8, decimal_places=2)
author = models.CharField(max_length=32)
3. 新建一个序列化类 (新建一个py文件名字随意)
from rest_framework.serializers import ModelSerializer
from App.models import Book
class BookModelSerializer(ModelSerializer):
class Meta:
model = Book
fields = '__all__'
4.视图中写视图类(CBV)
from rest_framework.viewsets import ModelViewSet
from .models import Book
from .ser import BookModelSerializer #ser指的是第三步中创建的py文件
class BooksViewSet(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
5.写路由关系
from django.contrib import admin
from django.urls import path
from rest_framework.routers import DefaultRouter
from App import views
router = DefaultRouter() # 可以处理视图的路由器
router.register('book', views.BooksViewSet) # 向路由中注册视图集
# 将路由器中的所有路由信息追溯到django的路由列表中
urlpatterns = [
path('admin/', admin.site.urls),
]
# 两个列表相加
urlpatterns += router.urls # router.urls是一个列表
6. 数据迁移
python manage.py makemigrations
python manage.py migrate
7.启动项目,测试
启动项目程序
3、postman测试
在postman
中测试,postman
中最后要加/
,浏览器会自动重定向,但postman
不会,所以在postman
中最后要加/
- 查数据
- 删数据
将2
删除后,就找不到数据
删除2
数据后,再查看所有数据
- 修改数据
修改完后,再次查询所有
- 增加数据
增加后再次查看所有数据
(四十)源码分析
cbv
ModelViewSet继承与View (djanog原生View)
path('books/',views.Books.as_view())#在这个地方应该写函数内存地址,views.Books.as_view()执行完,是个函数内存地址,as_view是一个类方法,类直接来调用,会把类自动传入
放入了一个view的内存地址,(View--》as_view--》内层函数)
class Books(View):
# 只能接收get请求
http_method_names = ['get']
def get(self, request):
print(self.request)
return HttpResponse('ok')
"""源码分析"""
#请求来了,如果路径匹配,会执行,函数内存地址(request)
def view(request, *args, **kwargs):
#request是当次请求的request
self = cls(**initkwargs)
self.setup(request, *args, **kwargs)
if not hasattr(self, 'request'): #实例化得到一个对象 Book对象
raise AttributeError(
"%s instance has no 'request' attribute. Did you override "
"setup() and forget to call super()?" % cls.__name__
)
return self.dispatch(request, *args, **kwargs)
def dispatch(self, request, *args, **kwargs):
#request就是当次请求的request selef是Book对象
if request.method.lower() in self.http_method_names:
#handle是自己写的Book类的get方法的内存地址
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs) #执行get(request)
APIView源码分析
#urls.py
path('booksapiview/', views.BooksAPIView.as_view()),在这个地方应该写函数内存地址
#views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
class BooksAPIView(APIView):
def get(self, request):
#request已经不是原生的django的request了,是drf自己定义的request对象
print(self.request)
return HttpResponse('ok')
"""源码分析"""
#APIView的as_view方法(类的绑定方法)
@classmethod
def as_view(cls, **initkwargs):
view = super().as_view(**initkwargs)#调用父类(View)的as_view方法,
view.cls = cls
view.initkwargs = initkwargs
#以后所有的请求都没有csrf认证了,只要继承了APIV i额外,就没有csrf认证了
return csrf_exempt(view)
#请求来了,路由匹配上,会执行view(request),调用了self.dispatch(),会执行apiview的self.dispatch()
#APIView的dispatch方法
def dispatch(self, request, *args, **kwargs):
self.args = args
self.kwargs = kwargs
#请求模块(解析模块)
# self.initialize_request(request, *args, **kwargs) 这里的request是当次请求的request
#request= self.initialize_request 这里的request是一个新的request对象
#重新包装成一个request对象,以后再用的request对象,就是新的request对象
request = self.initialize_request(request, *args, **kwargs)
self.request = request
self.headers = self.default_response_headers # deprecate?
try:
#
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)
#渲染模块
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
补充:
一切皆对象
def foo(a, b):
return a + b
foo.name = 'zhao'
print(foo(1, 3))
print(foo.name)
局部禁用csrf
#视图函数中加装饰器@csrf_exempt
#csrf_exempt(view)和在视图函数上加装饰器是一摸一样的
from django.views.decorators.csrf import csrf_exempt
urlpatterns = [
path('test/',csrf_exempt(views.test))#也是禁用csrf认证
]
drf的Request类
from rest_framework.request import Request
#只要继承了APIView,视图中的request对象,都是新的,也就是上面这个request的对象,
#老的request在新的request._request里
#以后使用request对象,就像使用之前的request是一摸一样的(因为重写了__getattr__方法)
def __getattr__(self, attr):
try:
return getattr(self._request, attr) #通过反射,取原生的request对象,取出属性和方法
except AttributeError:
return self.__getattribute__(attr)
#request.data 感觉是数据属性,其实是个方法,@property修饰了
它是一个字段,post请求不管使用社么编码,传过来的数据,都在request.data中
标签:self,request,rest,django,framework,api,https,com,view
From: https://www.cnblogs.com/zaosong/p/16939888.html