【问题标题】:How can i get sum of queryset lists and make jsonresponse?如何获取查询集列表的总和并生成 jsonresponse?
【发布时间】:2016-07-26 14:05:15
【问题描述】:

views.py

from itertools import chain

def post_list(request):

        i=1
        while i:
            list_i = Post.objects.filter(title__startswith="i")
            post_list = list(chain('' + ',' + 'list_i'))
            if len(post_list) >= 5 :
                break

    return JsonResponse(serializers.serialize('json', post_list), safe=False)

我想让 post_list 是 list_1、list_2、..、list_i 的总和,并使其序列化。

但它给我的 AttributeError 如下。

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/

Django Version: 1.9.7
Python Version: 3.5.2
Installed Applications:
[...I omitted]
Installed Middleware:
[...I omitted]

Traceback:

File "/home/keepair/djangogirls/myvenv/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
  149.                     response = self.process_exception_by_middleware(e, request)

File "/home/keepair/djangogirls/myvenv/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
  147.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/home/keepair/djangogirls/blog/views.py" in post_list
  33.     return JsonResponse(serializers.serialize('json', post_list), safe=False)

File "/home/keepair/djangogirls/myvenv/lib/python3.5/site-packages/django/core/serializers/__init__.py" in serialize
  129.     s.serialize(queryset, **options)

File "/home/keepair/djangogirls/myvenv/lib/python3.5/site-packages/django/core/serializers/base.py" in serialize
  83.             concrete_model = obj._meta.concrete_model

Exception Type: AttributeError at /
Exception Value: 'str' object has no attribute '_meta'

我该如何解决这个问题?

感谢您阅读我的问题。

【问题讨论】:

  • 我不明白你的代码。 list(chain('' + ',' + 'list_i')) 是做什么的?如果您有一个查询集list_i,为什么要在list(chain('' + ',' + 'list_i')) 中将其设为字符串?
  • 另外,getting sum of queryset 是什么意思?什么总和?
  • 我想要 list_1 + list_2 + list_3 ... 直到 Post 的总和为 gte=5。因为我是编程新手,所以我很难遵循 python itertools、chain 的规则。 list(chain('' + ',' + 'list_i')) 是我使用链功能的努力。还有什么好办法吗?
  • 哦,这就是你想要做的。不,itertools 链在这里完全不合适。
  • 我想要 list_i 的总和。如果 list_1 中有 5 个帖子,只需要 list_1,但是如果 list_1 中有 0 个帖子,list_2 中有 2 个帖子,list_3 中有 4 个帖子,我想要 list_1 和 list_2 和 list_3 的总和。

标签: python json django


【解决方案1】:

您的字符串值和文本值之间似乎存在严重的脱节。

In [126]: x = 3

In [127]: print("x")
x

In [128]: print(x)
3

In [129]: print(str(x))
3

根据您的代码,我非常肯定您认为print("x") 会打印出3。这永远不会像它所写的那样是真的。我这么说是因为你有

i=1
while i:
    list_i = Post.objects.filter(title__startswith="i")

除了一般错误之外,查看您的其他代码,我非常确定您希望这会返回以1 开头的Posts。它不会,它只会返回以'i' 开头的帖子。

在这里,您还创建了一个变量i,并且您正在使用while i,但您永远不会在任何地方更改i。如果您正在寻找的是确保您的帖子列表中至少包含 5 个项目,那么您就大错特错了。

首先,你需要一个帖子列表:

post_list = []

如果您想按帖子标题以1 开头然后2 等开头的数字进行过滤,那么您也需要一个计数器:

count = 0

现在,您需要在列表少于 5 个元素时循环:

while len(post_list) < 5:

然后您需要将内容附加到列表中。什么东西?你得到的帖子。但是我们也希望每次都增加这个数量,所以我们不会添加相同的帖子:

    count += 1
    post_list.extend(Post.objects.filter(title__startswith=str(count)))

将所有这些放在一起,您会得到:

def post_list(请求):

post_list = []
count = 0
while len(post_list) < 5:
    count += 1
    post_list.extend(Post.objects.filter(title__startswith=str(count)))

return JsonResponse(serializers.serialize('json', post_list), safe=False)

但是,我们还没有考虑一件事 - 如果您从未收到超过 5 个帖子怎么办?如果您的系统只有 4 个怎么办?这将(永远)以糟糕的方式结束——你将进入一个无限循环。所以我们应该添加另一个哨兵——我们从小学的计数中知道:

1,2,3,4,5,6,7,8,9,
10,
11,
12,
...
19,
20,
21,
...

9 以上的每个数字都将以数字 1-9 开头。因此,我们可以肯定地说,如果我们的计数达到 10+,那么我们的一个过滤器已经把它捡起来了。即使是 222,392,138,902 x 10^20 也是从 2 开始的。所以我们应该将 while 条件修改为:

while count < 10 and len(post_list) < 5:

而且我们会有一个我认为能满足你的需求的解决方案,除非你对过滤有不同的想法。

【讨论】:

  • 这对我来说是很好的讲座。正如你所想,英语不是我的第一语言,所以我在阅读和理解用英语写的内容时遇到了麻烦。但是你的解释对我很好。谢谢你。这对我很有帮助。
  • 如果我的回答是您问题的最佳解决方案,您应该通过单击左侧的复选标记将其标记为已接受
【解决方案2】:

您不应该使用chainchain 方法会将列表链接在一起,但您不希望所有这些都在一起,因此您应该使用普通列表方法:

def post_list(request):
    result = []
    i = 1
    while True:
        list_i = Post.objects.filter(title__startswith=str(i))
        result.extend(list_i)
        if len(result) >= 5:
            result = result[:5]
            break
        i += 1
    return JsonResponse(serializers.serialize('json', result), safe=False)

无意冒犯,但阅读您的代码,我觉得您缺乏 python/编程的一些基本知识。我建议你在开始 django 开发之前学习一些关于 python 的基础知识,这样可以节省你很多时间来弄清楚这样的东西。

【讨论】:

  • 哇,非常非常感谢。你是对的。我会记住你的建议。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
相关资源
最近更新 更多