英文:
ViewSet class variable
问题
以下是关于在Django Rest Framework中为GET
请求实现的逻辑的翻译:
class SomeViewSet(mixins.ListModelMixin,
GenericViewSet):
count = None
def get_queryset(self):
query_set = ... # 一些逻辑
self.count = query_set.count()
return query_set
def list(self, request, *args, **kwargs):
response = super().list(request, *args, **kwargs)
response.data = {'count': self.count,
'data': response.data}
return response
这段代码中,queryset
根据复杂逻辑计算,可能包含不同数量的对象,需要在GET
请求中返回。由于在list
函数内无法访问query_set
变量,且不希望复制query_set
的计算逻辑,所以决定使用类变量来处理。然而,仍然觉得这样做可能不太正确。还有哪些其他选择?
英文:
Now I have the following logic implemented for a GET
request in Django Rest Framework
:
class SomeViewSet(mixins.ListModelMixin,
GenericViewSet):
count = None
def get_queryset(self):
query_set = ... # some_logic
self.count = query_set.count()
return query_set
def list(self, request, *args, **kwargs):
response = super().list(request, *args, **kwargs)
response.data = {'count': self.count,
'data': response.data}
return response
That is, the queryset
is calculated according to complex logic, and it may contain a different number of objects that need to be returned in a GET
request, since I don’t have access to the query_set
variable inside the list function and I don’t want to copy the query_set
calculation logic, I decided do it with a class variable.
But still, the feeling that this is not very correct does not leave. What other options are there?
答案1
得分: 2
你可以在列表方法内部使用 self.get_queryset()
,而不是使用一个类变量。get_queryset
方法每次调用时都会执行,它会返回当前的查询集,所以可以这样:
class SomeViewSet(mixins.ListModelMixin,
GenericViewSet):
def get_queryset(self):
return ... # 一些逻辑
def list(self, request, *args, **kwargs):
queryset = self.get_queryset()
response = super().list(request, *args, **kwargs)
response.data = {'count': queryset.count(),
'data': response.data}
return response
编辑:
为了避免多次数据库查询的问题,你可以利用已经由 ListModelMixin
检索并存储在 response.data
属性中的查询集,像这样:
class SomeViewSet(mixins.ListModelMixin,
GenericViewSet):
def get_queryset(self):
return ... # 一些逻辑
def list(self, request, *args, **kwargs):
response = super().list(request, *args, **kwargs)
queryset = response.data
response.data = {'count': len(queryset),
'data': queryset}
return response
英文:
You can use self.get_queryset()
inside the list method instead of using a class variable. The get_queryset
method will be executed every time you call it, and it will return the current queryset so:
class SomeViewSet(mixins.ListModelMixin,
GenericViewSet):
def get_queryset(self):
return ... # some_logic
def list(self, request, *args, **kwargs):
queryset = self.get_queryset()
response = super().list(request, *args, **kwargs)
response.data = {'count': queryset.count(),
'data': response.data}
return response
Edit:
To avoid the issue of multiple database queries, you can make use of the queryset that is already retrieved by the ListModelMixin
and stored in the response.data
attribute so:
class SomeViewSet(mixins.ListModelMixin,
GenericViewSet):
def get_queryset(self):
return ... # some_logic
def list(self, request, *args, **kwargs):
response = super().list(request, *args, **kwargs)
queryset = response.data
response.data = {'count': len(queryset),
'data': queryset}
return response
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论