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&region=%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'> 两种文件对象的区别

  1. InMemoryUploadedFile: InMemoryUploadedFile 是Django中的一个类,用于处理上传的文件数据。它是从django.core.files.uploadedfile模块中导入的。这个类代表在内存中的文件,通常是通过HTTP POST请求上传的文件。它可以处理像图片、文档等各种文件类型的数据。InMemoryUploadedFile 提供了一些方法和属性,使您可以处理上传的文件数据,比如保存到磁盘、读取、获取文件名等。

  2. 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、效果

jingzhiz的接口文档

注意:使用 ModelViewSet 创建的视图函数,5个接口可以自动识别

 

posted @ 2023-08-28 16:44  凡人半睁眼  阅读(102)  评论(0编辑  收藏  举报