ViewSet类变量

huangapple go评论65阅读模式
英文:

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

huangapple
  • 本文由 发表于 2023年2月8日 21:49:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/75386759.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定