drf01 理论与安装
一、 Web开发模式
在开发Web应用中,有两种应用模式:
- 前后端不分离

- 前后端分离

#前后端混合开发(前后端不分离):返回的是html的内容,需要写模板
#前后端分离:只专注于写后端接口,返回json,xml格式数据
# xml格式
<xml>
<name>lqz</name>
</xml>
# json
{"name":"lqz"}
# java---》jsp
https://www.pearvideo.com/category_loading.jsp
#php写的
http://www.aa7a.cn/user.php
# python写的
http://www.aa7a.cn/user.html
#什么是动态页面(查数据库的),什么是静态页面(静止的html)
#页面静态化
二.、什么是接口
为了在团队内部形成共识、防止个人习惯差异引起的混乱,我们需要找到一种大家都觉得很好的接口实现规范,而且这种规范能够让后端写的接口,用途一目了然,减少双方之间的合作成本。
目前市面上大部分公司开发人员使用的接口服务架构主要有:restful、rpc。
# rpc 远程过程调用[远程服务调用]
http://www.xxx.com/api
post请求
/home?action=get_all_student¶ms=301&sex=1
def get_all_student(params,sex):
...
# restful: 翻译成中文: 资源状态转换.
# 把后端所有的数据/文件都看成资源.
'''
web项目中操作资源,无非就是增删查改.所以要求在地址栏中声明要操作的资源是什么,然后通过http请求动词来说明对资源进行哪一种操作.
POST http://www.lufei.com/api/students/ 添加学生数据
GET http://www.lufei.com/api/students/ 获取所有学生
DELETE http://www.lufei.com/api/students/<pk> 删除1个学生
'''
#百度地图的api接口
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&images/output=xml
三、 工具的使用
# postman是目前最好用的,模拟发送http请求的工具
# 双击安装,安装完成自动打开
# 解析json的网站
http://www.json.cn/
#请求头中User-Agent:客户端的类型
# 请求头中加其他参数:
# 批量接口导出和测试
一般常用的三种编码格式: urlencode json form-data(带文件)

四、restful接口设计规范
而对于数据资源分别使用POST、DELETE、GET、UPDATE等请求动作来表达对数据的增删查改。
| 请求方法 | 请求地址 | 后端操作 |
|---|---|---|
| GET | /students | 获取所有学生 |
| POST | /students | 增加学生 |
| GET | /students/ |
获取编号为pk的学生 |
| PUT | /students/ |
修改编号为pk的学生 |
| DELETE | /students/ |
删除编号为pk的学生 |
事实上,我们可以使用任何一个框架都可以实现符合restful规范的API接口。
参考文档:http://www.runoob.com/w3cnote/restful-architecture.html
1. 域名
应该尽量将API部署在专用域名之下。
https://api.baidu.com](https://api.baidu.com/
如果确定API很简单,不会有进一步扩展,可以考虑放在主域名下。
https://www.baidu.com/api
1 数据的安全保障:url链接一般都采用https协议进行传输 注:采用https协议,可以提高数据交互过程中的安全性
2 接口特征表现,一看就知道是个api接口
- 用api关键字标识接口url:
- [https://api.baidu.com](https://api.baidu.com/)
- https://www.baidu.com/api
注:看到api字眼,就代表该请求url链接是完成前后台数据交互的
2. 版本(Versioning)
应该将API的版本号放入URL。
http://www.example.com/app/1.0/foo
http://www.example.com/app/1.1/foo
3.多数据版本共存
- 在url链接中标识数据版本
- https://api.baidu.com/v1
- https://api.baidu.com/v2
注:url链接中的v1、v2就是不同数据版本的体现(只有在一种数据资源有多版本情况下)
3. 路径(Endpoint)
路径又称"终点"(endpoint),表示API的具体网址,每个网址代表一种资源(resource)
(1) 资源作为网址,只能有名词,不能有动词,而且所用的名词往往与数据库的表名对应。
举例来说,以下是不好的例子:
/getProducts books/
/listOrders
/retreiveClientByOrder?orderId=1
对于一个简洁结构,你应该始终用名词。 此外,利用的HTTP方法可以分离网址中的资源名称的操作。
GET /products :将返回所有产品清单
POST /products :将产品新建到集合
GET /products/4 :将获取产品 4
PATCH(或)PUT /products/4 :将更新产品 4
DELETE /products/4 :将产品 4删除
(2) API中的名词应该使用复数。无论子资源或者所有资源。
举例来说,获取产品的API可以这样定义
获取单个产品:http://127.0.0.1:8080/AppName/rest/products/1
获取所有产品: http://127.0.0.1:8080/AppName/rest/products
4 数据即是资源,均使用名词(可复数)
- 接口一般都是完成前后台数据的交互,交互的数据我们称之为资源
- https://api.baidu.com/users
- https://api.baidu.com/books
- https://api.baidu.com/book
注:一般提倡用资源的复数形式,在url链接中尽量不要出现操作资源的动词,错误示范:https://api.baidu.com/delete-user
- 特殊的接口可以出现动词,因为这些接口一般没有一个明确的资源,或是动词就是接口的核心含义
- https://api.baidu.com/place/search
- https://api.baidu.com/login
4. HTTP动词-不同请求方式
对于资源的具体操作类型,由HTTP动词表示。
常用的HTTP动词有下面四个(括号里是对应的SQL命令)。
- GET(SELECT):从服务器取出资源(一项或多项)。
- POST(CREATE):在服务器新建一个资源。
- PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
- DELETE(DELETE):从服务器删除资源。
还有三个不常用的HTTP动词。
- PATCH(UPDATE):在服务器更新(更新)资源(客户端提供改变的属性)。
- HEAD:获取资源的元数据。
- OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的。
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 - patch请求:局部修改主键为1的书
- https://api.baidu.com/books/1 - delete请求:删除主键为1的书
5. 过滤信息(Filtering)
查询参数
如果记录数量很多,服务器不可能都将它们返回给用户。API应该提供参数,过滤返回结果。
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:指定返回结果按照哪个属性排序,以及排序顺序
- https://api.example.com/v1/zoos?animal_type_id=1:指定筛选条件
6. 状态码(Status Codes)
服务器向用户返回的状态码和提示信息,常见的有以下一些(方括号中是该状态码对应的HTTP动词)。
7 响应状态码
7.1 正常响应
- 响应状态码2xx
- 200:常规请求
- 201:创建成功
- 204: 删除数据成功
7.2 重定向响应
- 响应状态码3xx
- 301:永久重定向
- 302:暂时重定向
7.3 客户端异常
- 响应状态码4xx
- 400: 请求错误
- 403:请求无权限
- 404:请求路径不存在
- 405:请求方法不存在
7.4 服务器异常
- 响应状态码5xx
- 500:服务器异常
- 507:存储错误
7. 错误处理(Error handling)
如果状态码是4xx,服务器就应该向用户返回出错信息。一般来说,返回的信息中将error作为键名,出错信息作为键值即可。
8 错误处理,应返回错误信息,error当做key
{
error: "无权限操作"
}
8. 返回结果
针对不同操作,服务器向用户返回的结果应该符合以下规范。
9 返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范
GET /collection:返回资源对象的列表(数组)
GET /collection/resource:返回单个资源对象
POST /collection:返回新生成的资源对象
PUT /collection/resource:返回完整的资源对象
PATCH /collection/resource:返回完整的资源对象
DELETE /collection/resource:返回一个空文档
9. 超媒体(Hypermedia API)
RESTful API最好做到Hypermedia(即返回结果中提供链接,不向其他API方法),使得用户不查文档,也知道下一步应该做什么。
10 需要url请求的资源需要访问资源的请求链接
# Hypermedia API,RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么
{
"status": 0,
"msg": "ok",
"results":[
{
"name":"肯德基(罗餐厅)",
"img": "https://image.baidu.com/kfc/001.png"
}
...
]
}
10. 其他
服务器返回的数据格式,应该尽量使用JSON,避免使用XML。
五 、drf的安装与使用
1. 安装与配置
# 安装drf的时候注意的django版本,这里推荐使用虚拟环境
参考地址:
https://www.cnblogs.com/wykang/p/17420544.html
# 安装
pip install djangorestframework==3.10.3
# 配置 - settings
INSTALLED_APPS = ['rest_framework']
2.drf简单使用
1.项目创建
# 1.项目创建
django-admin startproject project_drf
cd project_drf
python manage.py startapp app_drf
# INSTALLED_APPS = ['app_drf']
2.在models.py中写表模型
# 2.在models.py中写表模型
from django.db import models
# Create your models here.
class Book(models.Model):
nid=models.AutoField(primary_key=True)
name=models.CharField(max_length=32)
price=models.DecimalField(max_digits=5,decimal_places=2)
author=models.CharField(max_length=32)
3.在url配置
# 3.在url配置
from django.contrib import admin
from django.urls import path
from app_drf import views
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register('books', views.BooksViewSet)
urlpatterns = [
path("admin/", admin.site.urls),
path('books1/', views.Books.as_view()), # 在这个地方应该写个函数内存地址
path('booksapiview/', views.BooksAPIView.as_view()), # 在这个地方应该写个函数内存地址
]
# 两个列表相加
urlpatterns += router.urls
4.新建一个序列化类
# 4.新建一个序列化类
from rest_framework.serializers import ModelSerializer
from app01_demo.models import Book
class BookModelSerializer(ModelSerializer):
class Meta:
model = Book
fields = "__all__"
5.在视图写视图类
# 5.在视图写是视图类
from django.shortcuts import render,HttpResponse
from rest_framework.viewsets import ModelViewSet
from app_drf.models import Book
from app_drf.ser import BookModelSerializer
from rest_framework.views import APIView
from django.views import View
class BooksViewSet(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
class Books(View):
# 如果有个需求,只能接受get请求
http_method_names = ['get', ]
def get(self, request):
print(self.request)
return HttpResponse('ok')
class BooksAPIView(APIView):
def get(self, request):
# request 已经不是原生django的request了,是drf自己定义的request对象
# print(request._request)
# print(request.data)
print(request.method)
print(request.query_params) # get请求,地址中的参数
# 原来在
print(request.GET)
return HttpResponse('ok')
def post(self, request):
print(request.data) # urlencoded方式有数据,json格式也有,formdata也有数据
print(request.data.get('name'))
print(type( request.FILES.get('file')))
with open('xx.png','wb') as f:
for i in request.FILES.get('file'):
f.write(i)
# print(type(request.POST)) # 原生的POST
# print(request._request.POST)
from django.http.request import QueryDict
return HttpResponse('ok')
6.启动项目,在postman中测试即可
http://127.0.0.1:8000/books/

浙公网安备 33010602011771号