Web应用模式
在开发Web应用中,有两种应用模式:
前后端混合开发(前后端不分离):返回的是html的内容,需要写模板
前后端分离:只专注于写后端接口,返回json,xml格式数据
前后端不分离
前后端分离
api接口
为了在团队内部形成共识、防止个人习惯差异引起的混乱,我们需要找到一种大家都觉得很好的接口实现规范,而且这种规范能够让后端写的接口,用途一目了然,减少双方之间的合作成本。
通过网络,规定了前后台信息交互规则的url链接,也就是前后台信息交互的媒介
接口文档
一旦前后端分离以后,前端根本不清楚后端在写什么,要求的参数是什么不知道,返回什么格式的数据也不知道,所以每写一个接口,就要写一个接口文档
- 可以手动写(公司有平台,录到平台里)
- 自动生成(coreapi,swagger)
restful规范
1 api接口
-规定了前后台信息交互规则的url链接,也就是前后台信息交互的媒介
2 接口文档
-可以手动写(公司有平台,录到平台里,)
-自动生成(coreapi,swagger)
3 restful规范(10条,规定了这么做,公司可以不采用)
-1 数据的安全保障,通常使用https进行传输
-2 域名(会有api标识)
https://api.example.com 尽量将API部署在专用域名
https://127.0.0.0:8080/api/ API很简单
-3 请求地址中带版本,或者在请求头中
-https://127.0.0.0:8080/api/v1/
-4 任何东西都是资源,均使用名词表示 (尽量不要用动词)
-https://api.example.com/v1/books/
-https://api.example.com/v1/get_all_books(不符合规范)
-5 通过请求方式区分不同操作
-get获取
-post新增数据
-put/patch:patch是局部更新,put是全部(基本上更新都用put)
-delete:删除
-6 在请求路径中带过滤
https://api.example.com/v1/?name='金'&order=asc
https://api.example.com/v1/name?sortby=name&order=asc
-7 返回数据中带状态码
-http请求的状态码(2,3,4,5)
-返回的json格式中到状态码(标志当次请求成功或失败)
-8 返回数据中带错误信息
-错误处理,应返回错误信息,error当做key
-9 对不同操作,返回数据符合如下规范(这只是规范)
GET /books:返回资源对象的列表(数组)[{},{},{}]
GET /books/1:返回单个资源对象 {}
POST /books:返回新生成的资源对象 {新增的书}
PUT /books/1:返回完整的资源对象 {返回修改后的}
PATCH /books/1: 返回完整的资源对象 {返回修改后的}
DELETE /books/1: 返回一个空文档
{status:100,msg:查询成功,data:null}
-10 返回结果中带连接
Django Rest_Framework介绍和安装
核心思想: 缩减编写api接口的代码
Django REST framework是一个建立在Django基础之上的Web 应用开发框架,可以快速的开发REST API接口应用。在REST framework中,提供了序列化器Serialzier的定义,可以帮助我们简化序列化与反序列化的过程,不仅如此,还提供丰富的类视图、扩展类、视图集来简化视图的编写工作。REST framework还提供了认证、权限、限流、过滤、分页、接口文档等功能支持。REST framework提供了一个API 的Web可视化界面来方便查看测试接口。
特点
- 提供了定义序列化器Serializer的方法,可以快速根据 Django ORM 或者其它库自动序列化/反序列化;
- 提供了丰富的类视图、Mixin扩展类,简化视图的编写;
- 丰富的定制层级:函数视图、类视图、视图集合到自动生成 API,满足各种需要;
- 多种身份认证和权限认证方式的支持;[jwt]
- 内置了限流系统;
- 直观的 API web 界面;
- 可扩展性,插件丰富
drf安装
1 可以更方便的使用django写出符合resful规范的接口(不用也可以写符合规范的接口)
2 是一个app
3 安装 pip3 install djangorestframework
4 https://www.django-rest-framework.org/
drf简单使用
1 可以更方便的使用django写出符合resful规范的接口(不用也可以写符合规范的接口)
2 是一个app
3 pip3 install djangorestframework
4 https://www.django-rest-framework.org/
5 简单使用(csrf已经禁用掉了)
#路由
path('test/', views.Test.as_view()),
# 视图类
from rest_framework.views import APIView
from rest_framework.response import Response
class Test(APIView):
def get(self,request):
return Response({'name':'lqz','age':'19'})
def post(self,request):
return Response({'name': 'egon', 'age': '19'})
# 注册app
INSTALLED_APPS = [
'rest_framework'
]
# 在请求地址中访问
http://127.0.0.1:8001/test/
drf快速使用
views.py
from rest_framework.viewsets import ModelViewSet
from app import models
from app.serializer import BookSerializer
class BookView(ModelViewSet):
serializer_class =BookSerializer
queryset = models.Book.objects.all()
serializer.py
from rest_framework.serializers import ModelSerializer
from app import models
class BookSerializer(ModelSerializer):
class Meta:
model = models.Book
fields = '__all__'
urls.py
from rest_framework.routers import SimpleRouter
from app import views
router = SimpleRouter()
router.register('books', views.BookView)
urlpatterns = [
path('admin/', admin.site.urls),
]
urlpatterns += router.urls
在setting的app中配置
INSTALLED_APPS = [
'rest_framework'
]
models.py
class Book(models.Model):
name = models.CharField(max_length=32)
publish = models.CharField(max_length=32)
price = models.IntegerField()
CBV源码分析和APIView源码分析
path('test/',views.TestView.as_view()),
# path('test/',View类的as_view内部有个view闭包函数内存地址),
'''
1 path的第二个参数是:View类的as_view内部有个view闭包函数内存地址
2 一旦有请求来了,匹配test路径成功
3 执行第二个参数view函数内存地址(requset)
4 本质执行了self.dispatch(request)
5 通过反射去获得方法(如果是get请求,就是get方法)
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
6 执行get方法,传入参数
handler(request, *args, **kwargs)
'''
APIView的执行流程
# path('test/',APIView类的as_view内部是用了View的as_view内的view闭包函数),
'''
1 path的第二个参数是:APIView类的as_view内部是用了View的as_view内的view闭包函数
2 一旦有请求来了,匹配test路径成功
3 执行第二个参数view函数内存地址(requset),还是执行View的as_view内的view闭包函数,但是加了个csrf_exempt装饰器
4 所以,继承了APIView的所有接口,都没有csrf的校验了 (*****************)
5 执行self.dispatch(request)----》APIView类的
def dispatch(self, request, *args, **kwargs):
# 以后所有的request对象,都是****新的request对象***,它是drf的Request类的对象
request = self.initialize_request(request, *args, **kwargs)
self.request = request
try:
#整个drf的执行流程内的权限,频率,认证
self.initial(request, *args, **kwargs)
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
'''
### request = self.initialize_request(request, *args, **kwargs)
##返回的request对象是drf Request类的request对象
def initialize_request(self, request, *args, **kwargs):
return Request(
request,
parsers=self.get_parsers(),
authenticators=self.get_authenticators(),
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)
### *******以后,在视图类中使用的request对象已经不是原来的request对象了,现在都是drf的request对象了
#####你需要记住的
-0 所有的csrf都不校验了
-1 request对象变成了新的request对象,drf的request对象
-2 执行了权限,频率,认证
-3 捕获了全局异常(统一处理异常)
-4 处理了response对象,如果浏览器访问是一个样,postman访问又一个样
-5 以后,在视图类中使用的request对象已经不是原来的request对象了,现在都是drf的request对象了
Request对象分析
1 django 原生的Request:django.core.handlers.wsgi.WSGIRequest
2 drf的Request:rest_framework.request.Request
3 drf的request对象内有原生的request
request._request:原生的Request
4 在视图类中使用
request.method 拿到的就是请求方式,
正常拿,应该request._request.method
5 如何实现这种操作?
-对象.属性会触发 类的__getattr__方法
6 drf的Request类重写了__getattr__
def __getattr__(self, attr):
try:
# 去原生的request反射属性
return getattr(self._request, attr)
except AttributeError:
return self.__getattribute__(attr)
7 虽然视图类中request对象变成了drf的request,但是用起来,跟原来的一样,只不过它多了一些属性
-request.data #post请求提交的数据,不论什么格式,都在它中
-requst.query_params# get请求提交的数据(查询参数)
8 重点记住:
-drf的request对象用起来跟原来一样(重写了__getattr__)
-request.data #post请求提交的数据,不论什么格式,都在它中
-requst.query_params# get请求提交的数据(查询参数)
总结
1 cbv执行流程
-路由里写的是 类名.as_view(),
-as_view()执行完是一个闭包函数的内存地址
-当请求来了,路由匹配上就会调用 闭包函数(request)
-self.dispatch(requset)
-通过反射,去类中根据请求方式取方法,执行,把参数传入
2 APIView的执行流程
-以后写drf,最顶层都是APIView
-类名.as_view()是APIView,内部调用了父类的view
-在后加了去除csrf
-self.dispatch(requset)是APIView的
-包装新的request
-执行了权限,频率,认证
-处理了全局异常
-处理了响应
4 drf的Request类
-重写了__getattr__ :新的request用起来,跟之前一模一样
-drf的reqeust._request 是原来的request
-request.data :post,put,patch,请求的body体中的数据,都从data中取