一、Web 应用模式
有两种应用模式:
- 前后端不分离
前端页面看到的效果都是由后端控制,由后端渲染页面或重定向,也就是后端需要控制前端的展示,前端与后端的耦合度很高。
2. 前后端分离
在前后端分离的应用模式中,后端仅返回前端所需的数据,不再渲染HTML页面,不再控制前端的效果。至于前端用户看到什么效果,从后端请求的数据如何加载到前端中,都由前端自己决定,网页有网页的处理方式,App有App的处理方式,但无论哪种前端,所需的数据基本相同,后端仅需开发一套逻辑对外提供数据即可。
在前后端分离的应用模式中 ,前端与后端的耦合度相对较低。
在前后端分离的应用模式中,我们通常将后端开发的每个视图都称为一个接口,或者API,前端通过访问接口来对数据进行增删改查。
二、什么是接口
前台与后台进行信息交互的媒介 -- url链接
接口组成
- url链接 - http://127.0.0.1:8000/api/users/
- 请求方式 - get(查), post(增), put(整体改), patch(局部改), delete(删)
- 请求参数 - 拼接参数, 数据包参数(urlencoded, json, form-data)
- 响应结果 - 响应的 json数据
5. 开发阶段接口测试工具Postman
为什么要写接口文档
- 作为后台开发者, 要通过url将数据返回给前台
- 接口文档是给后台开发者, 前台开发者, 测试等各个相关项目组同事查看的, 方便团队开发(规则是后台指定的, 文档后台来写)
接口规范
为什么要制定接口规范?
- 在前后台分离的情况下, 后台可以采用不同的后台应用, 因为前后台的响应规则是一致的
- 按照一套规范来编写, 后台不管是什么语言, 前台都可以采用一样的交互方式.
- 与之相反, 后台也不用管前台以何种方式开发
通用的接口规范: Restful 接口规范
url 编写
- https 协议 - 保证数据的安全性
- api字眼 - 标识操作的是数据
- v1/v2 字眼 - 数据的多版本共存
- 资源复数 - 请求的数据称之为资源 用数据类别的复数
- 拼接条件 - 过滤群查接口数据 (https://api.baidu.com/books/?limit=3&ordering=-price)
请求方式
- /books/ - get - 群查
- /books/(pk)/ - get - 单查
- /books/ - post - 单增
- /books/(pk)/ - put - 单整体改
- /books/(pk)/ - patch - 单局部改
- /books/(pk)/ - delete - 单删
响应结果
- 网络状态码与状态信息:2xx | 3xx | 4xx | 5xx
- 数据状态码:前后台约定规则 - 0:成功 1:失败 2:成功无结果
- 数据状态信息:自定义成功失败的信息解释(英文)
- 数据本体:json数据
- 数据子资源:头像、视频等,用资源的url链接
- 基于restful接口规范的接口设计
三、Restful风格操作 ->>>> 前后端不分离
- view.py文件中写
################1.定义列表视图###############################
class BookListView(View):
'''
列表数据:BookInfo 数据 restful (GET,POST,PUT)
返回: JsonResponse
'''
#1.查询所有的图书
def get(self,request):
books=BookInfo.objects.all() #查询集
print(books)
#定义列表
book_list=[]
#遍历
for book in books:
#字典
book_dict={
'id':book.id,
'name':book.name,
'pub_date':book.pub_date,
'read_count':book.read_count,
'comment_count':book.comment_count,
'is_del':book.is_del,
'image':book.image.url if book.image else ''
}
#添加到列表中
book_list.append(book_dict)
print(book_list)
#返回数据 self=False不使用它的类型
return JsonResponse(book_list,safe=False)
pass
#2.添加图书
def post(self, request):
#获取前端传入的数据
json_bytes=request.body
#bytes 类型转换成json字符串
json_str=json_bytes.decode()
#再转成字典
book_dict=json.loads(json_str, encoding='utf-8')
#保存数据
book=BookInfo.objects.create(
name=book_dict['name'],
pub_date=book_dict['pub_date'],
)
#返回
book_dict = {
'id': book.id,
'name': book.name,
'pub_date': book.pub_date,
'read_count': book.read_count,
'comment_count': book.comment_count,
'is_del': book.is_del,
'image': book.image.url if book.image else ''
}
#status=201 返回状态码
return JsonResponse(book_dict,status=201)
pass
class BookDataView(View):
'''
详情视图
'''
# 1.查询单个图书 -根据id查找需要传参数
def get(self, request,pk):
try:
book =BookInfo.objects.get(id=pk)
except BookInfo.DoesNotExist:
return HttpResponse({"message","查询数据不存在!"},status=404)
#模型中的对象转换成字典
book_dict = {
'id': book.id,
'name': book.name,
'pub_date': book.pub_date,
'read_count': book.read_count,
'comment_count': book.comment_count,
'is_del': book.is_del,
'image': book.image.url if book.image else ''
}
return JsonResponse(book_dict,safe=False)
pass
# 2.修改图书 -根据id查找需要传参数
def put(self, request, pk):
try:
book = BookInfo.objects.get(id=pk)
except BookInfo.DoesNotExist:
return HttpResponse({"message", "查询数据不存在!"}, status=404)
#获取前端的数据--类似于添加数据
# 获取前端传入的数据
json_bytes = request.body
# bytes 类型转换成json字符串
json_str = json_bytes.decode()
# 再转成字典
book_dict = json.loads(json_str, encoding='utf-8')
#修改数据
book.name=book_dict['name']
book.pub_date=book_dict['pub_date']
book.save()
# 返回
book_dict = {
'id': book.id,
'name': book.name,
'pub_date': book.pub_date,
'read_count': book.read_count,
'comment_count': book.comment_count,
'is_del': book.is_del,
'image': book.image.url if book.image else ''
}
# status=201 返回状态码
return JsonResponse(book_dict, status=201)
# 3.删除图书 -根据id查找需要传参数
def delete(self, request, pk):
try:
book = BookInfo.objects.get(id=pk)
except BookInfo.DoesNotExist:
return HttpResponse({"message", "查询数据不存在!"}, status=404)
#删除
book.delete()
#返回状态码
return HttpResponse(status=204)
2. urls.py配置路径
####restful接口
path('books/',views.BookListView.as_view()), #查询所有的图书数据, 类视图;注意:as_view() 必须有()
#正则表达式
re_path(r'^books/(?P<pk>\d+)/$',views.BookDataView.as_view()), #查询详情数据, 类视图;注意:as_view() 必须有
3. 显示效果
1.查询所有的数据
2.添加数据
3.查询单个数据
4.修改数据
5..删除数据
四、DRF是什么?
drf框架的全称:diango-rest framework,是一种后端框架是基于restful风格的框架、该框架主要做的是前后的分离时接口的规范的编写
1. DRF和django的概念:
Django:将数据库的东西通过ORM的映射取出来,通过view文件,按照template文件排出的模板渲染成HTML。当用户请求相应的url时,返回相应的结果。
Django REST Framework: 将数据库的东西通过ORM的映射取出来,通过view和serializers文件绑定REST接口,当前端请求时,返回序列化好的json。
2.Django REST Framwork在Django的基础上的改变:
DRF是Django的超集(就是前者有的东西是后者没有的东西),去掉了模板的部分,提供了一个REST的接口,同时也提供了满足该接口的代码工作流。同时,在REST的规范下,升级了权限和分页等功能,增加了限流和过滤搜索等功能。
DRF和Django的区别?
如果用纯粹的django进行开发,基本上一个页面对应一个视图函数,而这个视图函数完成对数据的请求,数据库的增删改查操作,html页面的渲染,整理成完整的html页面通过http返回给浏览器,最终呈现效果
DRF是不同的前端人员在各自不同的平台上编写所呈现的效果,而后端人员只需要编写API,返回对应的json数据即可
序列化:前端向后端获取数据,这个过程叫做序列化(读取)
反序列化:前端向后端提交数据,这个过程叫做反序列化(写入)
五、环境安装与配置
DRF需要以下依赖:
- Python (3.5, 3.6, 3.7, 3.8, 3.9)
- Django (2.2, 3.0, 3.1)
DRF是以Django扩展应用的方式提供的,所以我们可以直接利用已有的Django环境而无需从新创建。(若没有Django环境,需要先创建环境安装Django)
1. 安装DRF
```shell
pip install djangorestframework
``
2. 添加rest_framework应用
我们利用在Django框架学习中创建的demo工程,在settings.py的INSTALLED_APPS中添加'rest_framework'。
3 创建序列化器:在books应用中新建Serializers.py用于保存该应用的序列化器。
''
创建一个Serializer.py文件,
再创建一个BookInfoSerializer用于序列化与反序列化。
- **model** 指明该序列化器处理的数据字段从模型类BookInfo参考生成
- **fields** 指明该序列化器包含模型类中的哪些字段,'__all__'指明包含所有字段
'''
from rest_framework import serializers
from books.models import BookInfo
class BookInfoSerializer(serializers.ModelSerializer):
"""图书数据序列化器"""
class Meta:
model=BookInfo
fields='__all__'
4 编写视图 books/view.py编写代码
# 导入相应的包#############
from rest_framework.viewsets import ModelViewSet
from .models import BookInfo
from books.Serializer import BookInfoSerializer
################2.定义类视图###############################
'''
1.导入序列化模块
2.使用序列化器,图书模型类
3.写视图,继承ModelViewSet,视图集viewsets
- **queryset** 指明该视图集在查询数据时使用的查询集
- **serializer_class** 指明该视图在进行序列化或反序列化时使用的序列化器
'''
class BookInfoView(ModelViewSet):
'''
定义类视图
指定查询集
'''
queryset = BookInfo.objects.all() #查询集
serializer_class = BookInfoSerializer #序列化或反序列化时使用的序列化器
5.定义路由
#导包
from rest_framework.routers import DefaultRouter
from books import views
#1. 可以处理视图的路由器
router=DefaultRouter()
#2. 向路由器中注册视图集
router.register(r'books',views.BookInfoView)
#3.将路由器中的所以路由信息追到到django的路由列表中
urlpatterns+=router.urls
6.http://127.0.0.1:8000/
列表数据:http://127.0.0.1:8000/books/
下面可以添加数据post提交
提交之后的显示
访问:http://127.0.0.1:8000/books/1
访问:http://127.0.0.1:8000/books/7