【问题标题】:"Cannot filter a query once a slice has been taken"“一旦获取切片,就无法过滤查询”
【发布时间】:2010-08-12 16:56:41
【问题描述】:

我收到此错误

渲染时捕获 AssertionError:获取切片后无法过滤查询。

在这条线上

{% if form.non_field_errors %} 

当我尝试这样做时

copy_pickup_address = ModelChoiceField(required=False, queryset=Address.objects.filter(shipment_pickup__user=user).order_by('-shipment_pickup__created')[:5])

但我需要对其进行切片,因为我只想要最后 5 个地址。它呈现得很好,直到我选择一个地址并提交表单。为什么不喜欢这样?我怎样才能绕过它?

【问题讨论】:

  • 仅供参考,我在使用ModelChoiceField 时也遇到了其他问题,所以我只是通过使用ChoiceField 并手动抓取模型来绕过这个问题......但我仍然不知道为什么我会收到这个愚蠢的错误。

标签: django


【解决方案1】:

解释在https://docs.djangoproject.com/en/1.8/ref/models/querysets/:

即使对未评估的 QuerySet 进行切片返回另一个未评估的 QuerySet,也不允许对其进行进一步修改(例如,添加更多过滤器或修改排序),因为这不能很好地转化为 SQL,而且它也没有明确的含义。

【讨论】:

    【解决方案2】:

    我不知道如何解决您的问题(似乎您已经解决了),但我认为这就是您收到错误的原因:https://docs.djangoproject.com/en/1.4/ref/models/querysets/

    “切片。正如限制查询集中所解释的,查询集可以是 切片,使用 Python 的数组切片语法。切片未评估 QuerySet 通常会返回另一个未计算的 QuerySet,但 Django 会 如果使用 slice 的“step”参数,则执行数据库查询 语法,并将返回一个列表。切片一个查询集 评估(部分或全部)也返回一个列表。”

    我猜你是在强制使用切片评估查询集,以便进一步过滤导致错误?

    【讨论】:

    • 这听起来与您刚刚引用的结论相反。 “切片未评估的 QuerySet 通常会返回另一个未评估的 QuerySet”——我没有使用“step”参数,所以我的查询仍应未评估,不是吗?
    • 不幸的是,我不确定...我离 Django 专家最远,只是想提供该链接,以便其他人可能知道在哪里更深入地挖掘,我知道一些文档是有时很难找到/识别。
    • 当前版本的文档解释它:见我的回答。
    【解决方案3】:

    这最终对我有用

    _latest_shipment_ids = [address.id for address in Address.objects.filter(shipment_pickup__user=user).order_by('-shipment_pickup__created')[:5]]
    copy_pickup_address = ModelChoiceField(
        required=False,
        queryset=Address.objects.filter(
            shipment_pickup__user=user,
            id__in=_latest_shipment_ids
        )
    )
    

    【讨论】:

      【解决方案4】:

      通过将我的查询集拉出代码的一侧然后在下一行过滤它,我已经解决了类似的错误。

      query = Address.objects.filter(shipment_pickup__user=user).order_by('-shipment_pickup__created')
      copy_pickup_address = ModelChoiceField(required=False, queryset=query[:5])
      

      不确定这是否适用于您的代码。

      【讨论】:

      • 不知道......但是这个问题与我不再相关,所以我会接受这个并希望它对其他人有用:)或者我......当我遇到它时再次走在路上:\
      • 我几年前就开始工作了,从那时起 django 制作这些的方式可能已经改变了。
      猜你喜欢
      • 1970-01-01
      • 2016-05-14
      • 1970-01-01
      • 2021-03-05
      • 2021-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-16
      相关资源
      最近更新 更多