对象不可迭代:过滤 QuerySet 以显示最新实例

Posted

技术标签:

【中文标题】对象不可迭代:过滤 QuerySet 以显示最新实例【英文标题】:Object is not iterable: Filtering QuerySet to display latest instance 【发布时间】:2016-05-09 14:49:21 【问题描述】:

我正在尝试使用 Django 在 QuerySet 中创建一个过滤器,该过滤器返回当前登录用户提交的最新实例。

到目前为止,我的 view.py 文件中有以下内容:

def transfer(request):

    title = 'Transfers'

    queryset = Transfer.objects.filter(user=request.user).latest('timestamp')

    context = 
        "title": title,
        "queryset": queryset,
    

    if request.method == "POST":
        print request.POST

    return render(request, "transfer.html", context)

但是这会返回错误

TypeError: 'Transfer' 对象不可迭代

到目前为止,我的 models.py 文件如下所示:

from django.db import models
from django.contrib.auth.models import User

class Transfer(models.Model):
    id = models.AutoField(primary_key=True)
    user = models.ForeignKey(User)
    amount = models.DecimalField(max_digits=10, decimal_places=2)
    timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)

而我的 html 文件以下列方式调用 QuerySet:

% if request.user.is_authenticated %
    <h2>Your Transfers</h2>
    % if queryset %
        % for instance in queryset %
            <p>Amount:  instance.amount  </p>
            <p>User:  instance.user  </p>
            <p>Date:  instance.timestamp </p>
        % endfor %
    % else %
        <h3>You have not made any transfers.</h3>
    % endif %

% endif %

任何建议将不胜感激!

【问题讨论】:

您的Transfer 类中没有user 属性。您可能需要更改为Transfer.objects.filter(username=request.user.username).latest('timestamp') 抱歉,我已将该模型字段更改为:user = models.ForeignKey(User) 你能相应地更新问题吗? 【参考方案1】:

latest 返回一个对象:最新的。因此,您不再将可迭代的查询集传递给模板,而是自然地无法迭代的单个实例。

不清楚你想在这里做什么;也许您只需要删除 for 循环,直接引用实例即可。或者,如果您确实想要不同,您可以迭代,您可能想要删除 latest 调用并仅按反向时间戳排序。

【讨论】:

我正在尝试显示当前使用以下登录的用户进行的最新传输:% if request.user.is_authenticated % &lt;h2&gt;Your Transfers&lt;/h2&gt; % if queryset % % for instance in queryset % &lt;p&gt;Amount: instance.amount &lt;/p&gt; &lt;p&gt;User: instance.user &lt;/p&gt; &lt;p&gt;Date: instance.timestamp &lt;/p&gt; % endfor % % else % &lt;h3&gt;You have not made any transfers.&lt;/h3&gt; % endif % % endif % 当我通过反向时间戳订购时,我得到了同样的错误:TypeError: 'Transfer' object is not iterable 你能显示整个视图(作为问题的编辑)吗? 啊,突然间错误消失了,您建议将视图更改为queryset = Transfer.objects.filter(user=request.user).reverse()[:1]!但是它现在显示的是最旧的实例,我希望它显示的是最新的。 你需要.order_by('-timestamp')【参考方案2】:

像这样更新你的查询

ueryset = Transfer.objects.filter(user=request.user).order_by('timestamp')[count_limit:]

[count_limit:] 表示您想要从顶部获取多少个对象。为了获得前 5 名,你可以做 [:5] 您不必添加 id 字段,因为 django 会自动添加。

【讨论】:

这会返回以下错误global name 'count_limit' is not defined count_limit 只是示例。这意味着如果您想获得前 5 个元素,请像 [5:] 哦,我明白了,queryset = Transfer.objects.filter(user=request.user).order_by('-timestamp')[:1] 效果很好!

以上是关于对象不可迭代:过滤 QuerySet 以显示最新实例的主要内容,如果未能解决你的问题,请参考以下文章

访问模板中的ModelForm queryset对象字段

为啥 QuerySet 迭代这么慢?

PySpark:在“NoneType”对象上过滤掉 RDD 元素失败是不可迭代的

TypeError:“KFold”对象不可迭代

Django Queryset 过滤器检查相关对象是不是存在

Django queryset - 在对象上应用过滤器时仅返回匹配的多记录