Django-drf面试题
什么是restful规范
RESTful是一种定义Web API接口的设计风格,尤其适用于前后端分离的应用模式中。
数据的安全保障:url链接一般都采用https协议进行传输(数据交互中安全性) 接口特性表现:一看就知道是个api接口,用api关键字标识接口url:https://api.baidu.com
多数据版本共存:在url链接中标识数据版本https://api.baidu.com/v1
数据即是资源,均使用名词(可复数),尽量不要出现动词 资源操作由请求方式决定(method):提供请求方式来标识增删改查动作 过滤,通过在url上传参的形式传递搜索条件:例如url后面?=搜索,分页,游标
查找模板的顺序
优先查找根目录下:template
根据app的注册顺序去每个app的template目录中查找
drf组件提供的功能
1、免除csrf认证
2、视图(1.APIView、2.ListAPIview、3.ListModelMixin)
3、权限
4、认证
5、解析器
6、筛选器
7、分页
8、序列化和数据校验:
可以对queryset进行序列化,也可以对用户提交的数据进行校验
source:无需加括号,在源码内部会去判断是否可以执行,可执行自动加括号
SerializerMethodField定义钩子方法
9、渲染器:把json数据渲染到drf自己的页面上
drf继承过哪些视图类,之间的区别
1、APIview
遵循了CBV模式,功能多但是需要自己写的代码也多
提供了免除csrf认证,版本处理、认证、权限、节流、解析器、筛选器、分页、序列化、渲染器
2、ListAPIView,RetrieveAPIView,CreateAPIView,UpdateAPIView,DestroyAPIView
第二种则在第一种的基础上,封装了许多我们需要自己的写的代码,许多功能的实现只需要给专属的变量名赋值就可以实现该功能
3、GenericViewSet、ListModelMixin,RetrieveModelMixin,CreateModelMixin,UpdateModelMixin,DestroyModelMixin
第三种则重构了APIView中的as_view()方法,结合请求方法和不同Mixin类的方法名从而进行执行不同的功能。与前面两种最主要的区别是url路由中as_view()方法中需要传值。
目前使用的主要目的是把第二种的bug(查询全部数据的功能和查询单个数据的功能无法在一个类中实现)实现在一个类中
GenericAPIView视图类的作用
作用:GenericAPIView主要为drf内部帮助我们提供增删查改的类,提供了执行流程和功能,我们在使用drf内置类做增删查改时,就可以通过自定义静态字段(类变量)或重写方法(get_queryset、get_serializer_class)来做一些更高级的定制
drf版本的实现过程
drf自带的版本类"DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.URLPathVersioning",
允许出现的版本"ALLOWED_VERSIONS": ['v1', 'v2'],
如果没有传版本,可以使用默认版本
default_version = api_settings.DEFAULT_VERSION
设置url中获取版本的变量,默认是version
version_param = api_settings.VERSION_PARAM
过程:
当前端传来请求,执行了as_view()方法,如果设置了全局版本或者进入了设置了版本的功能函数,则会先执行APIview类中dispatch方法,之后再执行initial方法,然后进入self.determine_version方法,里面会先判断是否有versioning_class,如果没有就返回(None,None),代表没有版本,有则执行versioning_class(URLPathVersioning)类中的determine_version方法,他会返回版本,里面会判断,如果获取到version为空则返回默认版本,并且还要判断是否存在允许出现的版本列表中,返回版本后再把版本号和版本分类分别赋值给request.version和request.versioning_scheme
drf组件认证的实现过程
当用户进行登录的时候,运行了登录类的as_view()方法,
1、进入了APIView类的dispatch方法
2、执行了self.initialize_request这个方法,是重定义request,并且得到了自己定义的认证类对象
3、执行self.initial方法中的self.perform_authentication,里面运行了user方法
4、再执行了user方法里面的self._authenticate()方法
5、然后执行了自己定义的类中的authenticate方法,自己定义的类继承了BaseAuthentication类,里面有 authenticate方法,如果自己定义的类中没有authenticate方法会报错。
6、把从authenticate方法得到的user和auth赋值给user和auth方法
7、这两个方法把user和auth的值赋值给了request.user:是登录用户的对象,request.auth:是认证的信息字典
drf组件权限的实现过程?
当用户执行一个业务的时候,运行了as_view方法
1、进入了APIView类的dispatch方法
2、进入self.initial方法中的self.check_permissions(request)方法
3、里面执行了for循环,把每个权限类实例化对象,
4、执行自己定义的权限类里面的has_permission方法,里面会判断request.user是否存在
5、不存在就返回False,存在就返回True
6、之后执行self.permission_denied报错方法,返回的是False就报错,可以自定义报错信息,在has_permission方法中写message = {"status": False, "error": "登录成功之后才能评论"},就实现了自定义报错
7、如果返回的是True就让他进入功能