繁体   English   中英

在自定义 django-rest-framework 操作中覆盖查询集是否安全

[英]Is it safe to override queryset in a custom django-rest-framework action

假设我有一个这样的查询集

class DataViewSet(viewsets.ModelViewSet):
    serializer_class = DataSerializer
    queryset = Data.objects.all()

    @action(detail=False, methods=['get'], url_path='viewers/sum')
    def viewers_sum(self, request):
        self.queryset = Data.objects.filter(foo="bar").order_by('-foo')
        return super().list(request)

如您所见,我在自定义操作viewers_sum中覆盖了查询集。 我的问题是这是否有可能导致其他操作出现问题,例如list() 在获得许可之前,我也遇到过类似的问题,我已经覆盖了一些尚未为下一个请求恢复的属性。

我试过调试这个,似乎没有问题,但我不明白它背后的原因。 而且它在生产服务器上的行为可能与我的开发服务器不同。

文档中,他们没有使用这种方法。 但我更喜欢这个,因为它感觉很干净(如果它是安全的)。

编辑

我想问题可以归结为:Django 是否为每个请求创建一个新的 ViewSets 实例,还是一个持久实例?

编辑 2

我通读了源代码,发现您可以通过 kwargs 来覆盖。 不过也不确定这是否“安全”。 似乎它正在工作,但同样,这是在调试服务器中。

class DataViewSet(viewsets.ModelViewSet):
    serializer_class = DataSerializer
    queryset = Data.objects.all()

    @action(
        detail=False,
        methods=['get'],
        url_path='viewers',
        queryset=Data.objects.none()
    )
    def viewers_sum(self, request):
        return super().list(request)

查询集是一个queryset变量,您正在更改queryset viewers_sum(...)方法内的查询集的值。

结果,一旦调用了viewers_sum(...)queryset的值就不会改变,并且有副作用。


最佳做法是什么?

您可以将get_queryset(...)方法覆盖为,

class DataViewSet(viewsets.ModelViewSet):
    serializer_class = DataSerializer

    def get_queryset(self): if self.action == "viewers_sum": return Data.objects.filter(foo="bar").order_by('-foo') return Data.objects.all()

    @action(detail=False, methods=['get'], url_path='viewers/sum')
    def viewers_sum(self, request):
        return super().list(request)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM