如果 queryset 和 get_queryset 都定义在继承自 GenericViewSet 的 Django ViewSet 上会发生什么
What happens if queryset and get_queryset are both defined on a Django ViewSet that inherits from GenericViewSet
我继承了一些 Django 代码,但我正在努力弄清楚以前的开发人员对他们的代码的意图。
配置了一个ViewSet,继承自GenericViewSet。在 class 中,它定义了一个 queryset
变量,但也定义了一个 get_queryset
方法。我正在努力从文档和教程中找出这到底意味着什么?更有趣的是,get_queryset
方法 returns 一个类型的查询集,但是 queryset
变量定义了不同的类型。
我希望的是将两个查询集结合起来(这是所需的行为,并且似乎发生在一台服务器上,而不是另一台服务器上,因此需要进行一些额外的调查才能找出原因)
代码如下:
class FeedbackFieldViewSet(NestedViewSetMixin,
customer_mixins.CustomerProviderMixin,
mixins.ListModelMixin,
viewsets.GenericViewSet):
##
# Instantiates and returns the list of permissions required by this viewset.
#
# @return The list of permissions.
#
def get_permissions(self):
# Maps action names to tuples of permission classes.
permissionDict = {
"list": self.listPermissionClasses,
}
if self.action in permissionDict:
return [permission() for permission in permissionDict[self.action]]
if self.request.method == "OPTIONS":
# Anyone can submit an options request
return []
raise ProgrammingException("A request with an unknown permission model was received.")
listPermissionClasses = (IsFeatureEnabled,)
##
# Overrides the get_queryset method to join the custom feedback fields
# with the default feedback fields.
#
def get_queryset(self):
queryset = super(FeedbackFieldViewSet, self).get_queryset().filter(
deleted = False,
recordContentType = ContentType.objects.get(
app_label = "hubpro_api",
model = "feedback"))
return list(chain(queryset, FeedbackField.objects.all()))
serializer_class = FeedbackFieldSerializer
feature = "feedback"
queryset = CustomField.objects.all()
视图集中get_queryset
方法的要点与
类似
def get_queryset(self):
return self.queryset
由于您已覆盖 get_queryset
方法并调用 super
,因此您正在更改结果。
get_queryset
和 self.queryset
有不同的用法,例如self.queryset
的定义用于确定路由器 url 定义中视图的基本名称(请参阅注释:http://www.django-rest-framework.org/api-guide/routers/#usage)如果您不提供查询集作为查看 DRF 将在路由器中引发错误。
在您的特定情况下(根据您的源代码片段显示的内容),queryset
、如果未在其他任何地方使用(无法根据此片段确定)没有用)!
我建议进行重构以简化可读性和清理问题,在查询集中为您在 get_queryset
方法中使用的过滤器创建一个自定义方法,我会删除 queryset
完全(如果它的安全取决于您的其余代码),因为下一个编码人员将需要像您一样深入研究代码才能理解它。
编码大约 80% 是阅读,20% 是编码,并且总是让代码比您发现的更好(~ 干净的代码,罗伯特·马丁)。
这可能对其他人没有用,但为了完整起见,我正在回答它。
实际上 queryset
和 get_queryset
查询集都合并了。看起来 get_queryset
对 super(FeedbackFieldViewSet, self).get_queryset()
的调用获取了查询集值 (CustomField.objects.all()
),然后 list(chain(queryset, FeedBackField,objects.all()))
将两个查询集组合在一起。
我的错误与分页有关,即缺少缺失值是因为它们不在结果的第一页上。
我继承了一些 Django 代码,但我正在努力弄清楚以前的开发人员对他们的代码的意图。
配置了一个ViewSet,继承自GenericViewSet。在 class 中,它定义了一个 queryset
变量,但也定义了一个 get_queryset
方法。我正在努力从文档和教程中找出这到底意味着什么?更有趣的是,get_queryset
方法 returns 一个类型的查询集,但是 queryset
变量定义了不同的类型。
我希望的是将两个查询集结合起来(这是所需的行为,并且似乎发生在一台服务器上,而不是另一台服务器上,因此需要进行一些额外的调查才能找出原因)
代码如下:
class FeedbackFieldViewSet(NestedViewSetMixin,
customer_mixins.CustomerProviderMixin,
mixins.ListModelMixin,
viewsets.GenericViewSet):
##
# Instantiates and returns the list of permissions required by this viewset.
#
# @return The list of permissions.
#
def get_permissions(self):
# Maps action names to tuples of permission classes.
permissionDict = {
"list": self.listPermissionClasses,
}
if self.action in permissionDict:
return [permission() for permission in permissionDict[self.action]]
if self.request.method == "OPTIONS":
# Anyone can submit an options request
return []
raise ProgrammingException("A request with an unknown permission model was received.")
listPermissionClasses = (IsFeatureEnabled,)
##
# Overrides the get_queryset method to join the custom feedback fields
# with the default feedback fields.
#
def get_queryset(self):
queryset = super(FeedbackFieldViewSet, self).get_queryset().filter(
deleted = False,
recordContentType = ContentType.objects.get(
app_label = "hubpro_api",
model = "feedback"))
return list(chain(queryset, FeedbackField.objects.all()))
serializer_class = FeedbackFieldSerializer
feature = "feedback"
queryset = CustomField.objects.all()
视图集中get_queryset
方法的要点与
def get_queryset(self):
return self.queryset
由于您已覆盖 get_queryset
方法并调用 super
,因此您正在更改结果。
get_queryset
和 self.queryset
有不同的用法,例如self.queryset
的定义用于确定路由器 url 定义中视图的基本名称(请参阅注释:http://www.django-rest-framework.org/api-guide/routers/#usage)如果您不提供查询集作为查看 DRF 将在路由器中引发错误。
在您的特定情况下(根据您的源代码片段显示的内容),queryset
、如果未在其他任何地方使用(无法根据此片段确定)没有用)!
我建议进行重构以简化可读性和清理问题,在查询集中为您在 get_queryset
方法中使用的过滤器创建一个自定义方法,我会删除 queryset
完全(如果它的安全取决于您的其余代码),因为下一个编码人员将需要像您一样深入研究代码才能理解它。
编码大约 80% 是阅读,20% 是编码,并且总是让代码比您发现的更好(~ 干净的代码,罗伯特·马丁)。
这可能对其他人没有用,但为了完整起见,我正在回答它。
实际上 queryset
和 get_queryset
查询集都合并了。看起来 get_queryset
对 super(FeedbackFieldViewSet, self).get_queryset()
的调用获取了查询集值 (CustomField.objects.all()
),然后 list(chain(queryset, FeedBackField,objects.all()))
将两个查询集组合在一起。
我的错误与分页有关,即缺少缺失值是因为它们不在结果的第一页上。