API 接口、接口文档
一、API 简介
1、前后端分离项目中
为了在团队内部形成共识、防止个人习惯差异引起的混乱,需要找到一种大家都觉得很好的接口实现规范,而且这种规范能够让后端写的接口,用途一目了然,减少双方之间的合作成本
-后端传后端:API接口
-前端传前端:html,css,js---》ajax---》后端交互---》通过调用api接口返回数据---》字符串---》转成js的数组,对象,字符串
2、前后端混合
-模版语法:dtl:django template language
-模版渲染:在后端完成
<script> var name="lqz"; var age =19; var hobby='篮球'; python hobby=篮球 var girls='{{ girls }}' python girls=['女孩1','女孩2'] </script>
注意:
在js中由于django的模版语法渲染是在后端完成的,后端给列表类型数据的时候就变成字符串而不是数组。
3、url和接口的区别
Web API接口和一般的url链接还是有区别的,Web API接口简单概括有下面四大特点
1. url:长得像返回数据的url链接
https://api.map.baidu.com/place/v2/search
2. 请求方式:get、post、put、patch、delete
采用get方式请求上方接口
3. 请求参数:json或xml格式的key-value类型数据
ak:6E823f587c95f0148c19993539b99295 region:上海 query:肯德基 output:json
4. 响应结果:json或xml格式的数据
https://api.map.baidu.com/place/v2/search?ak=6E823f587c95f0148c19993539b99295®ion=%E4%B8%8A%E6%B5%B7&query=%E8%82%AF%E5%BE%B7%E5%9F%BA&output=json
4、 典型的api接口长这样
- url地址
- 有请求方式
- 携带参数
- 返回格式是json,xml
二、练习题
1、写一个demo使用postman测试
-1 传用户名密码到后端,查询数据库,都对了---》返回json格式{code:100,msg:登录成功}---》urlencoded
-2 打印 request.POST
-3 打印 request.body
-4 传文件到后方
from django.views.decorators.csrf import csrf_exempt @csrf_exempt def api(request): if request.method == 'POST': name = request.POST.get('name') phone = request.POST.get('phone') file = request.FILES.get('file') print(file) # print(request.body) 大文件不能获取到二进制数据,因为http基于TCP流式协议,容易发生沾包 res = models.UserInfo.objects.filter(username=name, phone=phone).first() if res: print(name, phone) print(request.POST) # <QueryDict: {'name': ['jingzhiz'], 'phone': ['123123']}> print(request.body) # b'name=jingzhiz&phone=123123' dict_back = {'code': 200, 'msg': '后端返回数据: 用户名和电话验证成功!'} return JsonResponse(dict_back) elif file: dict_back = {'code': 200, 'msg': '后端返回数据: 上传文件成功!'} return JsonResponse(dict_back) else: dict_back = {'code': 200, 'msg': '后端返回数据:用户名和电话验证失败!'} return JsonResponse(dict_back)
注:
1. @csrf_exempt 装饰器是绕过csrf验证
2. request.body 不能取到大文件数据,因为http基于TCP流式协议,容易发生沾包
2、获取文件对象
def test_body(request): print('POST--->', request.POST) # POST---> <QueryDict: {'username': ['jingzhiz']}> print('File--->', request.FILES) # File---> <MultiValueDict: {'myfile': [<InMemoryUploadedFile: 10001.jpg (image/jpeg)>]}> # print('body--->', request.body) request.body不能接收大文件,http基于TCP的流式协议 from django.core.files.uploadedfile import InMemoryUploadedFile myfile = request.FILES.get('myfile') print(myfile.size) # 286995 print(myfile.name) # 10001.jpg # print('body--->', request.body) print(type(myfile)) # <class 'django.core.files.uploadedfile.InMemoryUploadedFile'> BASE_DIR = settings.BASE_DIR file_path = os.path.join(BASE_DIR, 'img') with open(f'{file_path}/{myfile.name}', 'wb') as f: print(type(f)) # <class '_io.BufferedWriter'> for line in myfile: f.write(line) return JsonResponse({'code': 100, 'msg': '请求成功'})
注意:
django中 <class 'django.core.files.uploadedfile.InMemoryUploadedFile'> 和 <class '_io.BufferedWriter'> 两种文件对象的区别
-
InMemoryUploadedFile:
InMemoryUploadedFile
是Django中的一个类,用于处理上传的文件数据。它是从django.core.files.uploadedfile
模块中导入的。这个类代表在内存中的文件,通常是通过HTTP POST请求上传的文件。它可以处理像图片、文档等各种文件类型的数据。InMemoryUploadedFile
提供了一些方法和属性,使您可以处理上传的文件数据,比如保存到磁盘、读取、获取文件名等。 -
BufferedWriter:
_io.BufferedWriter
是Python标准库中_io
模块中的一个类,用于对二进制数据进行缓冲写入。它是Python的内置文件写入对象,用于将数据写入到文件中,可以将数据缓冲一段时间,然后一次性写入文件,以提高写入效率。通常,您可以使用Python的内置open()
函数来创建一个文件对象,并使用BufferedWriter
来写入数据。
总结区别:
InMemoryUploadedFile
是Django特有的类,用于处理上传的文件数据,而BufferedWriter
是Python标准库提供的一种用于文件写入的工具。InMemoryUploadedFile
用于处理上传的文件数据,包括保存、读取、获取文件信息等。BufferedWriter
则是用于提高文件写入效率的工具,它不直接与上传文件相关。InMemoryUploadedFile
可以包含有关上传文件的元数据和其他信息,而BufferedWriter
则专注于将数据写入文件中。
请注意,这两个类有不同的上下文和用途,因此根据您的需求,选择适合的类来处理文件操作是很重要的。文件对象有相似的属性,可以使用点方法。
3、当前端发送json、urlencoded、form-data等数据格式后端都能取出来
-request.data 默认没有---》(装饰器)--->无论前端什么格式:josn,urlencoded---》后端取出来是字典
def warpper_request(func): def inner(request, *args, **kwargs): # request.data = {'username': '', 'password': ''} try: request.data = json.loads(request.body) except: request.data = request.POST res = func(request, *args, **kwargs) return res return inner @warpper_request def login1(request): username = request.data.get('username') password = request.data.get('password') print(username, password) user = User.objects.filter(username=username, password=password).first() if user: return JsonResponse({'code': 200, 'msg': '验证成功'}) else: return JsonResponse({'code': 101, 'msg': '验证失败'})
注意:
如果request.body中有值,表示前端传json数据的情况。没有值走request.POST赋值
4、总结
前端不同编码格式:
-urlencoded:
body体中 :username=lqz&password=123 django 的 request.POST取出值
-json:
body体中 :{"username":"lqz","password":"123"} django 的request.POST取不出值
-form-data:
body中格式固定:数据部分和文件部分--> request.POST能取出数据,取不出文件,文件都是从request.FILES中取
print(request.body):
b'----------------------------789048583058585187025897\r\nContent-Disposition: form-data; name="username"\r\n\r\nlqz\r\n文件二进制
二、接口文档
1、接口文档的展现形式:
1 word ,md ,写好传到公司的某个平台---》前端可以下载 2 自动生成接口文档---》后端通过配置--》把所写的接口都自动生成---》地址--》访问这个地址就能看到所有接口文档 3 公司内部搭建接口文档平台 - 开源:Yapi--->同学搭建一个,给搭建用 -https://zhuanlan.zhihu.com/p/366025001 - 自己开发(自研) 4 使用第三方平台(花钱)-->showdoc ....
2、接口文档如何写?需要有哪些东西?
-以用户注册接口为例: 1 接口描述 2 请求地址 3 请求方式 4 编码格式:json,urlencoded,form-data 5 请求参数:参数详解 -请求地址参数 -请求体参数 6 返回格式示例--》返回参数说明 7 备注(可有可无)--》错误码
3、自动生成接口文档
coreapi,
swagger,
Swagger UI入门部署 - 简书 (jianshu.com)
drf-yasg:
DRF-接口文档-(三方drf-yasg)-(简单使用): 使用自定义的认证类,使用jwt做token时,想要使用自动生成文档_东林牧之的博客-CSDN博客
三、自动生成接口文档之coreapi
1、配置
第一步:pip install coreapi 第二步:设置接口文档访问路径 from rest_framework.documentation import include_docs_urls urlpatterns = [ ... path('docs/', include_docs_urls(title='xxx')) ] 第三步:在models中,加注释 help_text class User(models.Model): username = models.CharField(max_length=32, help_text='用户账号名称') password = models.CharField(max_length=32, help_text='用户密码') 第四步:配置文件配置 REST_FRAMEWORK = { 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema', }
2、效果
注意:使用 ModelViewSet 创建的视图函数,5个接口可以自动识别