全称:django-rest frameworklinux
接口:什么是接口、restful接口规范(协议)git
CBV(基于FBV的基础上造成)、CBV生命周期源码----基于restful规范下的CBV接口web
请求生命周期:请求组件、解析组件、响应组件shell
序列化组件(序列化、反序列化简单来讲就是对象转为字符串、字符串转为对象,目的是为传输数据(传给别的语言或者存储))数据库
三大认证(重中之重):认证(用户是否合法)、权限(管理员、普通用户)、频率(次数过多限制)django
其余组件(过滤、筛选、排序、分页、路由)json
概念:联系两个物质的媒介,完成信息的交互。在web程序中,联系前台页面与后台数据库的媒介。api
web接口组成:浏览器
url:长得像返回数据的url连接。如api.baidu.map/search安全
(www.baidu.com不叫接口,叫url连接,访问只能拿到主页。api.baidu.map/search是接口,返回的是json数据)
请求参数:前台按照指定的key提供数据给后台。(必须是给定的,这样后台才能以此提取数据再到数据库查询返回)
响应数据:后台与数据库交互后,将数据反馈给前台。
所以,接口就是带着请求参数访问可以获得响应数据的url连接。
接口 = url + 请求参数 + 响应数据
接口规范:不一样后台语言,使用一样的接口返回一样的数据。
如何写接口:要写url和响应数据。若是将请求参数也加上,就是在写接口文档。
两大部分:
(1)url
1)用api关键字标识接口url。方式1:api.baidu.com;方式2:www.baudu.com/api
2)接口数据安全性决定优先选用https协议。
3)若是一个接口有多版本存在,须要在url中标识体现。以下的v1和v2
api.baidu.com/v1/.... api.baidu.com/v2/....
4)操做中的数据称为资源,在url中资源通常采用复数形式,一个接口能够归纳对该资源的多种操做方式。(一个url对应一个类,类里面能够有多个请求方法)
能够对操做隐藏,而且复用性更强(写动做了,只能适用这一个动做,不写其余动做均可以用)如api.baidu.com/books api.baidu.com/books/(pk)
5)请求方式有多种,用一个url处理如何让保证不混乱------经过不一样的请求方式标识不一样操做资源的方式
/books get 获取全部
/books post 增长一个(多个)
/books/(pk) delete 删除一个
/books/(pk) put 总体更新一个 #改一个用户
/books/(pk) patch 局部更新一个 #改一个用户的密码
6)资源每每涉及数据的各类操做方式:筛选、排序、限制
api.baidu.com/books/?search=宝马&ordering=-price&limit=3
(2)响应数据
1)http请求的响应会有响应状态码,接口用来返回操做的资源数据,也有本身操做数据结果的资源状态码(status 0表明操做资源成功,1表明操做失败,2表明操做成功,但没匹配结果)
注:资源状态码和http状态码不同,为先后台的约定
2)资源状态码的文字提示。
status ok “帐号有误或者密码有误”
3)资源自己
results
注:删除资源成功不作任何数据返回(只返回空字符串,连状态码、状态信息都不返回)
4)不能直接返回的资源(子资源、图片、视频等资源),返回该资源的url连接。
https://api.baidu.com/v1/books?limit=3 get|post|delete|put|patch { “status” : 0, “msg” : “ok”, “results”: [ { “title”: “三国”, “price”: 78, “img”: “https://.....” } ] }
(1)项目准备:
1.分发路由 在项目文件夹的urls复制一份到应用文件夹中。而后在项目文件夹的urls分发路由给app:导入include,而后url(r'^api/', include('api.urls'))。再在app文件夹的urls.py中分发路由给CBV 2.视图 在应用中分发路由前,先写类视图 from django.http import JsonResponse from django.views import View class Book(View): def get(self, request, *args, **kwargs): return JsonResponse('get ok', safe=False) def post(self, request, *args, **kwargs): return JsonResponse('get ok', safe=False) #safe默认为true,要返回字典。不是字典不然抛异常。
3.在应用urls下分发路由 from django.conf.urls import url from . import views #注意在应用中导入视图都是. 从当前应用中导入 urlpatterns = [ url(r'^books/', views.Book.as_view()), ]
4.定义模型类 (1)models.py中定义类 from django.db import models class Book(models.Model): title = models.CharField(max_length=64) price = models.DecimalField(max_digits=5, decimal_places=2) #整数、小数位 class Meta: #嵌套类(给上级类添加功能或指定标准) db_table = 'book' #自定义数据库表名 verbose_name = "book" #给模型起个可读的名字,默认是复数 verbose_name_plural = verbose_name #取消上面的复数 def __str__(self): #显示的内容 return '<<%s>>' % self.title
(2)数据库迁移 进入django的shell环境中:Tools----> run manage.py task 在shell环境中生成迁移文件:makemigrations。而后迁移:migrate
5.生成admin (1)在amin.py中注册而且导入模型 from django.contrib import admin port models admin.site.register(models.Book)
(2)建立用户 在shell环境中:createsuper建立超级用户,而后输入用户密码(邮箱不用)
|
(2)CBV的请求生命周期
请求如何到CBV下的get和post
a.请求过来,项目文件中路由分发给应用api的路由
b.应用分发路由走as_view函数。
views.Book.as_view() 保存一系列数据(request、args、**kwargs等)给Book对象,而后都给dispatch进行路由分发。
dispatch干的事:判断请求方式是否支持,而后返回(经过getattr)支持的这些请求方法(get、post等,在视图中自定义get、post的返回值)的结果。
c.经过dispatch就执行了CBV下请求方式的结果,返回结果
六大基础接口:获取一个、获取全部、增长一个、删除一个、总体更新一个、局部更新一个
十大接口:6大基础、群增、群删、总体群改、局部群改
1.在应用的urls.py下分发路由 url(r'^books/$', views.Book.as_view()), #必需要加$,不然后面匹配不到 url(r'^books/(?P<pk>.*)/$', views.Book.as_view()),有名分组 在视图函数中经过kwargs.get(pk)取到匹配的值
2.在views.py里写逻辑 class Book(View):
def get(self, request, *args, **kwargs): pk = kwargs.get('pk') #获取参数 if not pk: #群查接口 #操做数据库 book_obj_list = models.Book.objects.all() #序列化过程 book_list = [] for obj in book_obj_list: #将查到的对象序列化 dic = {} dic['title'] = obj.title dic['price'] = obj.price book_list.append(dic) return JsonResponse({ 'status' : 0, "msg" : "ok", "results": book_list, }, json_dumps_params={'ensure_ascii':False}) else: #单查接口 book_dic = models.Book.objects.filter(pk=pk).values( 'title', 'price').first() if book_dic: return JsonResponse({ 'status': 0, "msg": "ok", "results": book_dic, }, json_dumps_params={'ensure_ascii': False})
return JsonResponse({ 'status': 2, "msg": "no results", }, json_dumps_params={'ensure_ascii': False})
def post(self, request, *args, **kwargs): #前台经过urlencoded方式提交数据 try: book_obj = models.Book.objects.create(**request.POST.dict()) #create建立对象。将request.POST中存放的提交的关键词参数转化为字典以**方式传进去。没传参数,这边会报错。 if book_obj: return JsonResponse({ 'status': 0, "msg": "ok", “results”: {‘title’:book_obj.title, “price”:book_obj.price} }, json_dumps_params={'ensure_ascii': False}) except: #健壮性 return JsonResponse({ 'status': 1, "msg": "wrong params", }, json_dumps_params={'ensure_ascii': False}) return JsonResponse({ #可能操做数据库失败了 'status': 2, "msg": "created failed", }, json_dumps_params={'ensure_ascii': False})
|
JsonResponse返回时,中文会变成unicode,要加json_dumps_params={'ensure_ascii':False}选项。但在linux环境下的火狐浏览器,加了是乱码。
filter返回queryset对象,对象里是个列表(表名:对象信息(有自定义str就是自定义的信息))。first取里第一个对象(至关于print(第一个对象))values展现对应的对象里的值
<QuerySet [<Book: <<三国演义>>>]> #直接.filter
<<三国演义>> #.first()
<QuerySet [{'title': '三国演义', 'price': Decimal('56.00')}]> #.values('title','price')
{'title': '三国演义', 'price': Decimal('56.00')} #.values.first() 是个字典
上面序列化的工做很麻烦。drf就是为了方便序列化的。
postman能够完成不一样方式的请求:get、post、put等
postman发送数据包有三种方式:form-data、urlencoded、json. 原生django对urlencoded数据提交兼容。