Django-REST_FRAMEWORK

目录

  1. DRF规范
  2. 请求、响应
  3. 路由
  4. 视图
  5. 序列化
  6. 认证、权限、频率
  7. 过滤器、排序、分页、异常处理
  8. JWT
  9. RBAC

DRF规范

REST是Representational State Transfer的简称,中文翻译为“表征状态转移”或“表现层状态转化”。
十条RESTful API设计指南
1、数据的安全保障
	url一般采用https协议进行传输,可以提高数据交互过程中安全性
2、接口特征表现
	使用api关键字标识接口url,代表该url是完成前后台数据交互的
3、多数据版本共存
	当一种数据资源有多个版本,应在url中标识数据版本
4、数据即资源
	均使用名词复数表示数据资源
5、请求方式决定资源的操作方式
	GET :从服务器取出全部资源
	GET:后面加数字,从服务器取出单个资源
	POST:在服务器新建一个资源
	PUT:在服务器更新资源(客户端提供改变后的完整资源)
	PATCH:在服务器更新资源(客户端提供改变的属性)
	DELETE :从服务器删除资源
6、响应状态码
	200:常规请求
	201:创建成功
	300:永久重定向
	301:暂时重定向
	403:请求无权限
	404:请求路径不存在
	405:请求方法不存在
	500:服务器异常
7、响应结果
	针对不同操作,服务器向用户返回不同的结果
	GET:返回资源对象的列表(数组)
	GET:后面加数字,返回单个资源对象
	POST:返回新生成的资源对象
	PUT:返回完整的资源对象
	PATCH:返回完整的资源对象
	DELETE:返回一个空文档
8、过滤
	通过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:指定筛选条件
9、错误处理
	请求出错时,应返会错误信息
10、Hypermedia API
	返回结果中提供链接

请求、响应

请求

Request

基于Django的request进行重新封装,Django的request的属性都可以使用。
对于POST请求、PUT请求的数据通过request.data获取
对于GET请求的参数通过request.query_params获取

解析器

根据请求头content-type选择对应的解析器对请求体内容进行处理

JSONParser:仅处理content-type为application/json的请求头
FormParser:仅处理请求头content-type为application/x-www-form-urlencoded 的请求体
MultiPartParser:仅处理请求头content-type为multipart/form-data的请求体
FileUploadParser:仅处理上传的文件
局部使用
重写类的parser_classes属性
from rest_framework.views import APIView
from rest_framework.parsers import JSONParser, MultiPartParser, FileUploadParser, FormParser

class BookView(APIView):
    parser_classes = [JSONParser, MultiPartParser]			# 局部使用,重写类的parser_classes属性
    
    def get(self, request):
        pass
    
    def post(self, request):
        pass
全局使用
配置settings.py
REST_FRAMEWORK = {
   
	'DEFAULT_PARSER_CLASSES':[
		'rest_framework.parsers.JSONParser',
		'rest_framework.parsers.FormParser',
		'rest_framework.parsers.MultiPartParser'
	]
}

响应

Response
自己封装Response
1.继承Response
2.重写__init__方法
3.调用父类的__init__方法

from rest_framework.response import Response

class ApiResponse(Response):
    def __init__(self, code=100, msg='', err='', data=None, status=None, headers=None, **kwargs):
        dic = {
   'code': code}
        if msg:
            dic['msg'] = msg
        if err:
            dic['err'] = err
        if data:
            dic['data'] = data
        dic.update(kwargs)
        super().__init__(data=dic, status=status, headers=headers)
渲染器
内置渲染器
默认显示格式:BrowsableAPIRenderer
	访问URL方式:
		http://127.0.0.1:8000/test/?format=api
		http://127.0.0.1:8000/test.api
		http://127.0.0.1:8000/test/
		
显示json格式:JSONRenderer
	访问URL方式:
		http://127.0.0.1:8000/test/?format=json
		http://127.0.0.1:8000/test.json
		http://127.0.0.1:8000/test/
		
显示表格格式:AdminRenderer
	访问URL方式:
		http://127.0.0.1:8000/test/?format=admin
		http://127.0.0.1:8000/test.admin
		http://127.0.0.1:8000/test/
		
显示表单格式:HTMLFormRenderer
	访问URL方式:
		http://127.0.0.1:8000/test/?format=form
		http://127.0.0.1:8000/test.form
		http://127.0.0.1:8000/test/

自定义显示模板格式:TemplateHTMLRenderer
局部使用
重写视图类的renderer_classes属性
from rest_framework.views import APIView
from rest_framework.renderers import HTMLFormRenderer, BrowsableAPIRenderer

class BookView(APIView):
    renderer_classes = [HTMLFormRenderer, BrowsableAPIRenderer]  # 局部使用,重写类的renderer_classes属性

    def get(self, request):
        pass

    def post(self, request):
        pass	
全局使用
配置settings.py
REST_FRAMEWORK = {
   
	'DEFAULT_RENDERER_CLASSES':['rest_framework.renderers.JSONRenderer',
								'rest_framework.renderers.BrowsableAPIRenderer']
}

路由

自定义路由(原始方法)

from django.urls import path, re_path
from app01 import views

urlpatterns = [
    path('test/', views.TestView.as_view()),
    re_path(r'^test/(?P\d+)$', views.TestView.as_view())
]

半自动路由(视图类继承ViewSetMixin)

传入一个字典{
   '请求方式''视图对应的函数名'}
from django.urls import path, re_path
from app01 import views


urlpatterns = [
    path('test/', views.TestView.as_view({
   'get': 'list', 'post': 'create'})),		# 传入一个字典{'请求方式':'视图对应的函数名'}
    re_path(r'test/(?P\d+)$', views.TestView.as_view({
   'get': 'retrieve', 'put': 'update', 'delete': 'destroy'}))
]

全自动路由(自动生成)

1.导入自动生成路由的类
2.实例化
3.注册视图函数
4.拼接路由

# urls
from rest_framework.routers import SimpleRouter, DefaultRouter
from app01 import views

route1 = SimpleRouter()										# 实例化
route2 = DefaultRouter()
route1.register('app01/test1', views.TestView)				# 注册视图函数,第一个参数为路由地址,第二给参数为视图类
route2.register('app01/test2', views.Test2View)

urlpatterns += route1.urls									# 拼接路由,urls为自动生成的路由列表
urlpatterns += route2.urls

action装饰器:函数使用action装饰器装饰后,会自动生成路由
# views.py
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from app01 import models
from utils import ser


class TestView(ModelViewSet):
    queryset = models.AgvTestRecord.objects.all()
    serializer_class = ser.TestSer

    @action(methods=['get'], detail=True, url_path='ccc')
   	"""
   	methods:请求方式列表
    detail:决定是否带有pk值
    	当为True时生成的路由:^app01/test1/(?P[^/.]+)/ccc/$ [name='agvtestrecord-action']
    	当为False时生成的路由:^app01/test1/ccc/$ [name='agvtestrecord-action']
    url_path:生成的url路径名,默认为被装饰函数名
    url_name:反向解析名,默认为被装饰函数名
    """
 
    def action(self, request, *args, **kwargs):
        return Response('OK')

视图

两个视图基类

ApiView:基类,继承View
GenericView:基类,继承ApiView
ApiView
from rest_framework.views import ApiView
from utils.utils import ApiResponse
from app01 import models
from utils import sers

常用类属性:
	parser_classes:元组或列表,配置解析器类
	renderer_classes:元组或列表,配置渲染器类
	authentication_classes:元组或列表,配置认证类
	permission_classes:元组或列表,配置权限类
	throttle_classes:元组或列表,配置频率类

class TestView(APIView):
    def get(self, request, *args, **kwargs):
        pk = kwargs.get('pk', None)
        if pk:
            obj = models.AgvTestRecord.objects.filter(pk=pk).first()
            ser_obj = sers.TestSer(obj)
            return ApiResponse(code=100, msg='success', data=ser_obj.data)
        else:
            obj = models.AgvTestRecord.objects.all()
            ser_obj = sers.TestSer(obj, many=True)
            return ApiResponse(code=100, msg='success'

你可能感兴趣的:(Django,django,restful,python)