【一】前后端开发模式
【1】前后端混合开发
-
目前还有不少公司在使用flask 混合 和Django 混合
-
例如之前做的bbs项目
-
模板:dtl语法:django template language 模板语法
-
{{ }}
-
{% %}
-
-
在后端渲染: qs对象 --- 循环写到模版中 ---模版语法写的
-
渲染完后---模版---纯粹的html,css,js 不会再含有模版语法
-
返回到客户端浏览器 --- 看到好看的样式
-
-
如果要做混合开发
-
需要会后端,还需要稍微会一点前端 前端后端配合进行全栈开发
-
【2】前后端分离开发
-
后端只做后端内容 --- 前端只做前端内容
-
后端只需要写API接口
-
前端专门做前端的内容
-
最后进行前后端连调
【二】api接口
【1】什么是api接口
-
为了在团队内部形成共识、防止个人习惯差异引起的混乱,我们需要找到一种大家都觉得很好的接口实现规范,而且这种规范能够让后端写的接口,用途一目了然,减少双方之间的合作成本。
-
通过网络,规定了前后台信息交互规则的url链接,也就是前后台信息交互的媒介
127.0.0.1:8080/login/?name=knight&age=19 127.0.0.1:8080/books/
【2】api接口的特点
-
url:长得像返回数据的url链接
-
请求方式:get、post、put、patch、delete
-
采用get方式请求上方接口
-
-
请求参数:地址栏中参数 和 请求体中参数:urlencoded,form-data,json(用的多)
-
json或xml格式的key-value类型数据
-
ak:6E823f587c95f0148c19993539b99295
-
region:上海
-
query:肯德基
-
output:json
-
-
响应结果:json或xml格式的数据
-
上面的output参数值决定了响应数据的格式
# 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=xml # json格式 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 { "status":0, "message":"ok", "result_type":"poi_type", "results":[ { "name":"肯德基(美兰店)", "location":{ "lat":31.40884, "lng":121.357373 }, "address":"罗芬路1088号", "province":"上海市", "city":"上海市", "area":"宝山区", "street_id":"", "telephone":"(021)33703920", "detail":1, "uid":"efa262ccec2ce3be9b68b4a8" }, { "name":"肯德基(丁香店)", "location":{ "lat":31.225372, "lng":121.549768 }, "address":"世纪大道2002号", "province":"上海市", "city":"上海市", "area":"浦东新区", "street_id":"", "telephone":"(021)68544927", "detail":1, "uid":"00586108ae5beabc47e274ad" }, ] }
-
【三】接口测试工具
-
Postman: 同时支持各种操作系统平台,是测试接口的首选工具
-
Apifox:更适合需要快速进行接口测试、管理和文档编写的团队,特别是一体化解决方案的需求较为突出的场景。
【四】restful规范(面试可能会问)
-
REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征性状态转移)。 它首次出现在2000年Roy Fielding的博士论文中。
-
RESTful是一种定义Web API接口的设计风格,尤其适用于前后端分离的应用模式中。
-
这种风格的理念认为后端开发任务就是提供数据的,对外提供的是数据资源的访问接口,所以在定义接口时,客户端访问的URL路径就表示这种要操作的数据资源。
-
事实上,我们可以使用任何一个框架都可以实现符合restful规范的API接口
【1】数据的安全保障
-
url链接一般都采用https协议进行传输,比http协议安全
-
注:采用https协议,可以提高数据交互过程中的安全性
【2】接口特征表现
-
用api关键字标识接口url:
注:看到api字眼,就代表该请求url链接是完成前后台数据交互的
【3】多数据版本共存
-
在url连接中标识数据版本
注:url链接中的v1、v2就是不同数据版本的体现(只有在一种数据资源有多版本情况下)
【4】数据即是资源,均使用名词(可复数)
-
接口一般都是完成前后台数据的交互,交互的数据称之为资源
注:一般提倡用资源的复数形式,在url链接中不要出现操作资源的动词,错误示范:https://api.baidu.com/delete-user
-
特殊的接口可以出现动词,因为这些接口一般没有一个明确的资源,或是动词就是接口的核心含义
【5】资源操作由请求方式决定(method)
-
操作资源一般都会涉及到增删改查,我们提供请求方式来标识增删改查动作
-
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 - delete请求:删除主键为1的书
-
【6】过滤,通过在url上传参的形式传递搜索条件
-
https://api.example.com/v1/zoos?limit=10:指定返回记录的数量
-
https://api.example.com/v1/zoos?offset=10:指定返回记录的开始位置
-
https://api.example.com/v1/zoos?page=2&per_page=100:指定第几页,以及每页的记录数
-
https://api.example.com/v1/zoos?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序
【7】响应状态码
-
正常响应(响应状态码2xx)
-
200:常规请求
-
201:创建成功
-
-
重定向响应(响应状态码3xx)
-
301:永久重定向
-
302:暂时重定向
-
-
客户端异常(响应状态码4xx)
-
403:请求无权限
-
404:请求路径不存在
-
405:请求方法不存在
-
-
服务器异常(响应状态码5xx)
-
500:服务器异常
-
【8】错误处理
-
错误处理:应返回错误信息,error当做key
{ error: "无权限操作" }
【9】返回结果
-
返回结果:针对不同操作,服务器向用户返回一个结果应该符合一些规范
GET /collection:返回资源对象的列表(数组) GET /collection/resource:返回单个资源对象 POST /collection:返回新生成的资源对象 PUT /collection/resource:返回完整的资源对象 DELETE /collection/resource:返回一个空文档
【10】请求链接
-
当需要url请求的资源时,需要访问资源的请求链接
# 响应数据要有状态码、状态信息以及数据本身 { "status": 0, "msg": "ok", "results":[ { "name":"肯德基(罗餐厅)", "location":{ "lat":31.415354, "lng":121.357339 }, "address":"月罗路2380号", "province":"上海市", "city":"上海市", "area":"宝山区", "street_id":"339ed41ae1d6dc320a5cb37c", "telephone":"(021)56761006", "detail":1, "uid":"339ed41ae1d6dc320a5cb37c" } ... ] }
【五】序列化
api接口开发,最核心最常见的一个过程就是序列化,所谓序列化就是把数据转换格式,序列化可以分两个阶段:
序列化: 把我们识别的数据转换成指定的格式提供给别人
例如:我们在django中获取到的数据默认是模型对象,但是模型对象数据无法直接提供给前端或别的平台使用,所以我们需要把数据进行序列化,变成字符串或者json数据,提供给别人
反序列化:把别人提供的 数据转换/还原成 我们需要的格式。
例如:前端js提供过来的json数据,对于python而言就是字符串,我们需要进行反序列化换成模型类对象,这样我们才能把数据保存到数据库中
【六】Django Rest_Framework
drf是什么:django rest framwork,django框架上 一个可以快速实现restful规范接口的 快速开发框架
核心思想:缩减编写api接口的代码
Django REST framework是一个建立在Django基础之上的Web 应用开发框架,可以快速的开发REST API接口应用。在REST framework中,提供了序列化器Serialzer的定义,可以帮助我们简化序列化与反序列化的过程,不仅如此,还提供丰富的类视图、扩展类、视图集来简化视图的编写工作。REST framework还提供了认证、权限、限流、过滤、分页、接口文档等功能支持。REST framework提供了一个API 的Web可视化界面来方便查看测试接口。
官方文档:Home - Django REST framework
github: GitHub - encode/django-rest-framework: Web APIs for Django. 🎸
特点
-
提供了定义序列化器Serializer的方法,可以快速根据Django ORM或者其他库自动 序列化/反序列化
-
提供了丰富的类视图、Mixin扩展类,简化视图的编写
-
丰富的定制层级:函数视图、类视图、视图集合到自动生成API,满足各种需求
-
多种身份认证和权限认证方式的支持
-
内置了限流系统
-
直观的API web界面
-
可扩展性,插件丰富
【七】drf安装
当前Django版本来到了5版本,但是开发追求稳定,使用Django4版本 最新drf支持django4.x以上 django:pip3 install django==4.2.14 drf:pip3 install djangorestframework --upgrade # 3.15.2 这里的 --UPgrade 是指安装最新版本的drf
【八】drf使用小案例
在项目中如果使用rest_framework框架实现API接口,主要有以下三个步骤:
将请求的数据(如json格式)转换为模型类对象 操作数据库 将模型类对象转换为响应的数据(如JSON格式)
-
创建Django项目
-
创建app
-
添加rest_framework应用:在settings.py的INSTALLED_APPS中添加’rest_framework’。
INSTALLED_APPS = [ ... 'rest_framework', ]
-
创建模型表 models.py
from django.db import models # Create your models here. class Book(models.Model): name = models.CharField(max_length=64) price = models.IntegerField()
-
连接数据库setting.py
DATABASES = { # 'default': { # 'ENGINE': 'django.db.backends.sqlite3', # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), # }, 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': "students", "HOST": "127.0.0.1", "PORT": 3306, "USER": "root", "PASSWORD":"123", }, }
-
迁移数据库 makemigrations migrations
-
配置路由
-
urls.py
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path("api/v1/", include("app01.urls")) ]
-
app01\urls.py
from .views import BookView from rest_framework.routers import SimpleRouter router = SimpleRouter() router.register("books", BookView, "books") # 向路由器中注册视图集 urlpatterns = [ ] urlpatterns += router.urls
-
视图类 app01\views.py
from .models import Book from rest_framework.viewsets import ModelViewSet from .serializer import BookSerializer class BookView(ModelViewSet): serializer_class = BookSerializer queryset = Book.objects.all() # queryset 指明该视图集在查询数据时使用的查询集 # serializer_class 指明该视图在进行序列化和反序列化时 使用的序列化器
-
新建文件app01\serializer.py
from rest_framework import serializers from .models import Book class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = "__all__" # model 指明该序列化器处理的数据字段从模型类Book参考生成 # fields 指明该序列化器包含模型类中的哪些字段,’all‘指明包含所有字段
-
查看所有
-
添加
-
查看单个
-
修改
-
返回修改之后的结果
-
-
删除
-
返回空
-
【九】drf学习内容
-
请求和响应
-
request:请求对象:请求方式,请求携带的数据
-
request.GET,request.POST,requset.body,request.META:请求头中得
-
四件套
-
HTTPResponse('sdfs')
-
JsonResponse(字典列表)
-
render(request,模版文件)
-
-
drf也有自己的请求和响应
-
request
-
Response 的对象
-
-
-
序列化类:Serializer
-
做序列化
-
做反序列化
-
反序列化的校验
-
-
视图类:drf提供了非常多 视图类可以继承
-
路由
-
认证:登录认证
-
权限
-
频率限制
-
统一返回错误
-
jwt:登录认证用
-
基于角色的访问控制
【补充】
# get请求能不能再请求体中携带数据? 能,但一般都是post或者put请求在请求体中携带数据 # 总结: Django视图类或者视图函数的request request.POST:只针对于post请求的urlencoded编码格式 才会有数据 request.GET:请求地址栏中的参数 get post delete put <QueryDict: {'key': ['key', '99']}> 上面这个是类字典:取出key的值方式 只取一个:request.GET.get('key') 两个都取:request.GET.getlist('key') request.body:无论什么请求,无论什么编码格式,都在里面 http不同编码格式 urlencoded:在请求体中是 key=value&key=value json:在请求体中是 {"name":"knight","age":19} form-data: asdfasdf-------数据部分 asdfasdfasdf-----文件部分