0

我继承了一些 Django 代码,我正在努力弄清楚以前的开发人员对他们的代码的意图。

配置了一个 ViewSet,它继承自 GenericViewSet。在类中,它定义了一个queryset变量,但也定义了一个get_queryset方法。我正在努力从文档和教程中弄清楚这甚至意味着什么?更有趣的是,该get_queryset方法返回一个类型的查询集,但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()
4

3 回答 3

5

有不同的用法get_querysetself.queryset例如self.queryset用于确定路由器 url 定义中视图的基本名称的定义(参见注释: http: //www.django-rest-framework.org/api-guide/routers/#用法)如果您不提供查询集作为视图 DRF 的属性,则会在路由器中引发错误。

在您的特定情况下(根据您的源代码片段显示)queryset如果它没有在其他任何地方使用(根据此代码片段无法确定),则没有用!

我对重构以简化可读性和清除问题的建议是在查询集中为您在方法中使用的过滤器创建一个自定义方法get_queryset,我将queryset完全删除(如果它的安全性取决于您的代码的其余部分),因为下一个编码员需要像您那样深入研究代码才能理解它。

编码大约是阅读 20% 编码的 80%,并且总是让代码比你发现的更好(~干净的代码,robert c. martin)。

于 2017-10-04T09:21:06.887 回答
2

get_queryset视图集中的方法正在做什么的要点是

def get_queryset(self):
    return self.queryset

由于您已经覆盖了get_queryset方法和调用super,因此您正在更改结果。

于 2017-10-04T08:35:18.327 回答
1

这可能对其他人没有用,但为了完整起见,我正在回答它。

事实上,queryset和查询集都get_queryset被合并了。看起来get_queryset调用super(FeedbackFieldViewSet, self).get_queryset()获取查询集值(CustomField.objects.all())然后list(chain(queryset, FeedBackField,objects.all()))是组合两个查询集的内容。

我的错误与分页有关,即丢失的值丢失了,因为它们不在结果的第一页上。

于 2017-10-04T09:22:34.870 回答