请教一个关于 Django REST Framework 中 GenericAPIView 类的 self.request 属性的问题

2019-08-09 17:58:22 +08:00
 fourstring

根据 Django REST Framework 的官方文档,rest_framework.generic包中 GenericAPIView 提供了用于响应 HTTP 请求的 Handler method,而ListMixin等 Mixin 类则提供了 list/create 等执行逻辑的 Action method.

这两种方法的共性是除了隐式求值的 self 参数之外,所接受的第一个参数都是 request,即rest_frameworkRequest类的实例。

但是GenericAPIViewAPI 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 呢?非常感谢!

3995 次点击
所在节点    Django
3 条回复
qqxx520
2019-08-09 20:35:54 +08:00
bnm965321
2019-08-09 20:36:05 +08:00
说一下我的理解,list/action 之类的 HTTP method 映射方法,应该是为了和 Django class based view 的参数签名保持一致。

其实我觉 API 设计时候不把 request 单独放在方法的参数签名里面的,是为了不增加记忆负担,使用 self.request 更加自然一些。
fourstring
2019-08-09 20:40:05 +08:00
@qqxx520 #1
@bnm965321 #2 非常感谢!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/590549

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX