Django-rest-framework入门规范
文章目录
一、web应用开发模式
在web应用开发中,有两种开发模式
1.前后端不分离
前后端混合开发(前后端不分离):返回的是html的内容,需要写模板,前端看到的效果是由后端进行控制的
缺点:只适用于纯网页的应用
优点:有利于网站的seo优化
2.前后端分离
前后端分离:后端只返回所需的数据,至于数据怎么进行展示,由前端自己控制,后端专注于写接口,返回json,xml格式数据
关键点:到静态页面文件服务器请求静态页面,静态文件服务器返回静态页面,然后JS请求Django后端,Django后端返回JSON或者XML格式的数据。
优点:可以对接不同类型的客户端
缺点:不利于SEO优化
二、API接口
1.RESTFUL介绍
REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”或“表现层状态转化”。
2.RESTful API设计指南
参考资料 阮一峰 理解RESTful架构
3.API与用户的通信协议
总是使用HTTPs协议。
4.RestFul API接口设计规范
api接口
- 规定了前后台信息交互规则的url链接,也就是前后台信息交互的媒介
接口文档:
- 可以手动写(公司有平台,录到平台里)
- 自动生成(coreapi,swagger)
5.restful规范(10条,规定了这么做,公司可以不采用)
-
数据的安全保障,通常使用https进行传输
-
域名中会含有API标识
https://api.example.com 尽量将API部署在专用域名
https://127.0.0.0:8080/api/ API很简单
-
请求地址中带版本信息,或者在请求头中
https://127.0.0.0:8080/api/v1/
-
任何东西都是资源,均使用名词表示 (尽量不要用动词)
https://api.example.com/v1/books/
https://api.example.com/v1/get_all_books(不符合规范)
-
请求方式区分不同操作
-
get获取:从服务器取出资源(一项或多项)
-
post新增数据:在服务器新建一个资源
-
put/patch:patch是局部更新,put是全部(基本上更新都用put)
-
delete:从服务器中删除
-
-
在请求路径中带过滤
- 通过在url上传参的形式传递搜索条件
https://api.example.com/v1/?name=‘金’&order=asc
https://api.example.com/v1/name?sortby=name&order=asc
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:指定筛选条件
-
返回数据中带状态码
-
http请求的状态码
-
返回的json格式中到状态码(标志当次请求成功或失败)
200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。 201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。 202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务) 204 NO CONTENT - [DELETE]:用户删除数据成功。 400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。 401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。 403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。 404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。 406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。 410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。 422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。 500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。
-
-
返回数据中带错误信息
-
错误处理,应返回错误信息,error当做key
{ error: "Invalid API key" }
-
-
对不同操作,返回数据符合如下规范(这只是规范)
GET /books:返回资源对象的列表(数组)[{},{},{}] GET /books/1:返回单个资源对象 {} POST /books:返回新生成的资源对象 {新增的书} PUT /books/1:返回完整的资源对象 {返回修改后的} PATCH /books/1: 返回完整的资源对象 {返回修改后的} DELETE /books/1: 返回一个空文档 {status:100,msg:查询成功,data:null}
-
返回结果中带连接
RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。
{"link": { "rel": "collection https://www.example.com/zoos", "href": "https://api.example.com/zoos", "title": "List of zoos", "type": "application/vnd.yourformat+json" }}
三、postman的使用
后端写好接口要测试,后端开发要使用一个工具测试接口。
Postman是一款接口调试工具,是一款免费的可视化软件,同时支持各种操作系统平台,是测试接口的首选工具。
Postman可以直接从官网:https://www.getpostman.com/downloads/下载获得,然后进行傻瓜式安装。
也可以使用网页版APIZZ:https://www.apizza.net/
工作面板:
get请求:
post请求:
案例:请求百度地图
比较规范的接口案例:
# 响应数据要有状态码、状态信息以及数据本身
{
"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"
}
...
]
}
四、drf的安装与介绍
1.Django Rest_Framework介绍
-
核心思想:缩减编写api接口的代码
-
Django REST framework是一个建立在Django基础之上的Web 应用开发框架
-
可以更方便的使用django写出符合resful规范的接口(不用也可以写符合规范的接口)
官方文档:https://www.django-rest-framework.org/
github: https://github.com/encode/django-rest-framework/tree/master
环境安装与配置
DRF需要以下依赖:
- Python (2.7, 3.2, 3.3, 3.4, 3.5, 3.6)
- Django (1.10, 1.11, 2.0)
DRF是以Django扩展应用的方式提供的,所以我们可以直接利用已有的Django环境而无需从新创建。(若没有Django环境,需要先创建环境安装Django)
特点:
- 提供了定义序列化器Serializer的方法,可以快速根据 Django ORM 或者其它库自动序列化/反序列化;
- 提供了丰富的类视图、Mixin扩展类,简化视图的编写;
- 丰富的定制层级:函数视图、类视图、视图集合到自动生成 API,满足各种需要;
- 多种身份认证和权限认证方式的支持;[jwt]
- 内置了限流系统;
- 直观的 API web 界面;
- 可扩展性,插件丰富
安装DRF
前提需要安装Django
pip3 install djangorestframework
注意:使用DRF需要下settings中的app注册INSTALLED_APPS
:
使用DRF实现API三个步骤
接下来就可以使用DRF提供的功能进行api接口开发了。在项目中如果使用rest_framework框架实现API接口,主要有以下三个步骤:
- 将请求的数据(如JSON格式)转换为模型类对象
- 操作数据库
- 将模型类对象转换为响应的数据(如JSON格式)
五、drf的基本使用
-
views.py
# 在视图中写视图类 from rest_framework.viewsets import ModelViewSet from app import models from app.serializer import BookSerializer class BookView(ModelViewSet): serializer_class =BookSerializer queryset = models.Book.objects.all()
-
serializer.py
# 在app目录下中新建一个serializer.py 序列化类 from rest_framework.serializers import ModelSerializer from app import models class BookSerializer(ModelSerializer): class Meta: model = models.Book fields = '__all__'
-
urls.py
from rest_framework.routers import SimpleRouter from app import views router = SimpleRouter() # 可以处理视图的路由器 router.register('books', views.BookView) # 向路由器中注册视图集 # 将路由器中的所有路由信息追加到Django的路由列表中 urlpatterns = [ path('admin/', admin.site.urls), ] # 两个列表相加, router.urls 列表 urlpatterns += router.urls
-
在setting的app中配置
# settings注册app INSTALLED_APPS = [ 'rest_framework' ]
-
models.py
# 创建表模型 class Book(models.Model): name = models.CharField(max_length=32) publish = models.CharField(max_length=32) price = models.IntegerField()
-
最后启动项目,在请求地址中访问:http://127.0.0.1:8001/books/
六、自定义restAPI
需求:
设计一套符合RestAPI风格的接口,提供以下5个接口:
1. 获取所有图书数据:GET /books/
2. 新增一本图书数据:POST /books/
3. 获取指定的图书数据(根据id):GET /books/(?P<pk>\d+)/
4. 修改指定的图书数据(根据id):PUT /books/(?P<pk>\d+)/
5. 删除指定的图书数据(根据id):DELETE /books/(?P<pk>\d+)/
实现代码:
# 2个类视图
class BookListView(View):
# GET /books/
def get(self, request):
"""
获取所有图书数据:
1. 查询所有图书的数据
2. 将图书的数据进行返回
数据格式:json 状态码:200
"""
# 1. 查询所有图书的数据
books = BookInfo.objects.all() # QuerySet
# 组织数据
books_li = []
for book in books:
book_dict = {
'id': book.id,
'btitle': book.btitle,
'bpub_date': book.bpub_date,
'bread': book.bread,
'bcomment': book.bcomment,
'image': book.image.url if book.image else ''
}
books_li.append(book_dict)
# 2. 将图书的数据进行返回
# 注意点:将list转换为json数据时,需要将safe设置False
return JsonResponse(books_li, safe=False)
# POST /books/
# 参数:客户端传递 btitle,bpub_date,通过json传递
def post(self, request):
"""
新增一本图书数据:
1. 获取参数并进行校验:request.body->decode->json.loads
2. 创建图书并添加到数据库
3. 将新增的图书数据进行返回
数据格式:json 状态码:200
"""
pass
class BookDetailView(View):
# GET /books/(?P<pk>\d+)/
def get(self, request, pk):
"""获取指定的图书数据(根据id)"""
pass
# PUT /books/(?P<pk>\d+)/
def put(self, request, pk):
"""修改指定的图书数据(根据id)"""
pass
# DELETE /books/(?P<pk>\d+)/
def delete(self, request, pk):
"""删除指定的图书数据(根据id)"""
pass