[英]What happens if queryset and get_queryset are both defined on a Django ViewSet that inherits from GenericViewSet
I've inherited some Django code and I am struggling to work out what the previous developers have intended with their code.我继承了一些 Django 代码,我正在努力弄清楚以前的开发人员对他们的代码的意图。
There is a ViewSet which is configured, which inherits from GenericViewSet.有一个已配置的 ViewSet,它继承自 GenericViewSet。 In the class it defines a queryset
variable but also defines a get_queryset
method.在该类中,它定义了一个queryset
变量,但也定义了一个get_queryset
方法。 I'm struggling to work out from the docs and tutorials what this even means?我正在努力从文档和教程中找出这意味着什么? What's more interesting is that the get_queryset
method returns a queryset of one type, but the queryset
variable defines a different type.更有趣的是get_queryset
方法返回一种类型的查询集,但queryset
变量定义了不同的类型。
What I'm hoping for is for both querysets to be combined (which is the desired behaviour, and which appears to be happening on one server, but not another, so some additional investigation will be needed to work out why)我希望将两个查询集结合起来(这是所需的行为,并且似乎发生在一台服务器上,而不是另一台服务器上,因此需要进行一些额外的调查来找出原因)
Code below:代码如下:
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()
There are different usages for get_queryset
and self.queryset
eg the definition of self.queryset
is used to determine the basename of a view in the router's url definition (see Notes on: http://www.django-rest-framework.org/api-guide/routers/#usage ) if you don't provide a queryset as an attribute of the view DRF will raise an error in the router.有不同的用途get_queryset
和self.queryset
例如定义self.queryset
用于确定在路由器的网址定义视图的基本名称(见注: http://www.django-rest-framework.org/ api-guide/routers/#usage ) 如果您不提供查询集作为视图 DRF 的属性将在路由器中引发错误。
In your specific case (from what your source snippet shows) there is no use for the queryset
, if it is not used anywhere else (cannot say for sure based on this snippet)!在您的特定情况下(根据您的源代码片段显示的内容),如果没有在其他任何地方使用queryset
,则它没有用处(无法根据此代码片段确定)!
My suggestions for a refactoring to ease the readability and clear things up would be to create a custom method in the queryset for the filter you use in the get_queryset
method and I would remove the queryset
completely ( if its safe depends on the rest of your code ) because the next coder will need to dig through the code like you did to understand it.我的重构,缓解可读性和清晰的东西的建议是创建在查询集为您在使用过滤器自定义的方法get_queryset
方法,我会删除queryset
完全(如果它的安全依赖于你的代码的其余部分) 因为下一个编码员将需要像您一样深入了解代码才能理解它。
Coding is about 80% reading 20% coding and always leave the code better than you found it (~ clean code, robert c. martin).编码大约是 80% 阅读 20% 编码,并且总是让代码比你发现的更好(~干净的代码,robert c. martin)。
The gist of what get_queryset
method in viewsets is doing is something along the lines of get_queryset
方法的要点是
def get_queryset(self):
return self.queryset
Since you have overridden the get_queryset
method and calling super
, you're altering the result.由于您已覆盖get_queryset
方法并调用super
,因此您正在更改结果。
This probably won't be useful for anyone else, but for completeness I'm answering it.这可能对其他人没有用,但为了完整起见,我正在回答它。
Indeed both the queryset
and get_queryset
querysets get combined.事实上,无论是queryset
和get_queryset
查询集得到结合。 It looks like the get_queryset
call to super(FeedbackFieldViewSet, self).get_queryset()
gets the queryset value ( CustomField.objects.all()
) and then the list(chain(queryset, FeedBackField,objects.all()))
is what combines the two querysets.看起来get_queryset
调用super(FeedbackFieldViewSet, self).get_queryset()
获取查询集值( CustomField.objects.all()
)然后list(chain(queryset, FeedBackField,objects.all()))
是什么结合两个查询集。
My bug was to do with paging, ie the missing values were missing because they weren't on the first page of results.我的错误与分页有关,即缺失值缺失,因为它们不在结果的第一页上。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.