Python 在自定义django rest框架操作中重写queryset安全吗
假设我有一个这样的查询集Python 在自定义django rest框架操作中重写queryset安全吗,python,django,django-rest-framework,Python,Django,Django Rest Framework,假设我有一个这样的查询集 类数据视图集(viewsets.ModelViewSet): 序列化程序\u类=数据序列化程序 queryset=Data.objects.all() @操作(detail=False,methods=['get'],url\u path='viewers/sum') 定义和(自身、请求): self.queryset=Data.objects.filter(foo=“bar”).order_by('-foo')) return super().list(请求) 如您
类数据视图集(viewsets.ModelViewSet):
序列化程序\u类=数据序列化程序
queryset=Data.objects.all()
@操作(detail=False,methods=['get'],url\u path='viewers/sum')
定义和(自身、请求):
self.queryset=Data.objects.filter(foo=“bar”).order_by('-foo'))
return super().list(请求)
如您所见,我在自定义操作viewers\u sum
中覆盖了queryset。我的问题是,这是否有可能导致其他操作出现问题,如list()
。我以前在权限方面也遇到过类似的问题,我在下一个请求中覆盖了一些尚未恢复的属性
我试着调试这个,看起来没有问题,但我不明白背后的原因。而且它在生产服务器上的行为可能与在我的开发服务器上的行为不同
实际上,他们没有使用这种方法。但我更喜欢这个,因为它感觉很干净(如果安全的话)
编辑
我想问题可以归结为:
Django是为每个请求创建一个新的ViewSet实例,还是一个持久实例
编辑2
我通读了源代码,发现可以将kwargs传递给override。
但也不确定这是否“安全”。看起来它正在工作,但再一次,这是在调试服务器中
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
是一个类变量,您正在viewers\u sum(…)
方法中更改queryset
的值
因此,调用viewers\u 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)
类数据视图集(viewsets.ModelViewSet):
序列化程序\u类=数据序列化程序
def get_queryset(自我):
如果self.action==“viewers\u sum”:
返回Data.objects.filter(foo=“bar”).order_by('-foo')
返回Data.objects.all()
@操作(detail=False,methods=['get'],url\u path='viewers/sum')
定义和(自身、请求):
return super().list(request)
我在我的原始帖子中添加了一个编辑,你知道这是否是一个安全的使用方法吗?我想我们可以传递以\u class
结尾的类变量(例如序列化器\u class
),因此,我认为queryset
不属于这个标准。顺便说一句,你能把你推荐的源代码递给我吗?我想你是对的。此页面位于def action()
下。