根据 Django REST Framework 的官方文档,rest_framework.generic
包中 GenericAPIView 提供了用于响应 HTTP 请求的 Handler method,而ListMixin
等 Mixin 类则提供了 list/create 等执行逻辑的 Action method.
这两种方法的共性是除了隐式求值的 self 参数之外,所接受的第一个参数都是 request,即rest_framework
的Request
类的实例。
但是GenericAPIView
的API Reference中还提到了get_queryset
方法,并且说明:
May be overridden to provide dynamic behavior, such as returning a queryset, that is specific to the user making the request.
也就是说继承GenericAPIView
的子类可以通过重写get_queryset
方法来根据请求动态返回在可供 Action method 使用的 queryset.
问题在于,get_queryset
以及上面文档中还提到的get_object
方法都不接受 request 作为除了 self 之外的第一个参数,并且在文档的示例代码中,作者使用self.request
来访问当前所处理的 request。
def get_queryset(self):
user = self.request.user
return user.accounts.all()
那么,既然有了这种机制,为什么各种 Handler method 以及 Action method 都要接受 request 作为第一个参数呢?
此外,这里可以看到 GenericAPIView 的继承树。但从它的继承树中,我并没有看到任何 Attribute 名为 request,也没有任何 Property 名为 request。
根据 Python 的 Attribute Resolution Order 机制,也不存在 Mixin 类中提供的方法无法访问 GenericAPIView 中的 self.request 属性的问题(如果它存在的话。)
在是否接受 request 这一参数的问题上,为什么这些方法会存在这样的差别?在继承 Mixin 以及 GenericAPIView 的子类中,使用何种方法访问当前处理的 request 呢?非常感谢!
1
qqxx520 2019-08-09 20:35:54 +08:00 via Android 1
|
2
bnm965321 2019-08-09 20:36:05 +08:00 1
说一下我的理解,list/action 之类的 HTTP method 映射方法,应该是为了和 Django class based view 的参数签名保持一致。
其实我觉 API 设计时候不把 request 单独放在方法的参数签名里面的,是为了不增加记忆负担,使用 self.request 更加自然一些。 |
3
fourstring OP |