【问题标题】:Is slicing a queryset same as slicing the list used in __in clause? Can't understand this behavior切片查询集是否与切片 __in 子句中使用的列表相同?无法理解这种行为
【发布时间】:2014-10-02 20:02:56
【问题描述】:

我有一个 Story 模型,它通过 django-tagging 应用程序包含一个 TagField。 我正在获取特定标签的故事列表。在功能上我的代码运行良好,但我遇到了一个我不太理解的行为。

以下代码正确地为我提供了所需的故事列表。

    ct = ContentType.objects.get_for_model(Story)
    ti = TaggedItem.objects.filter(tag__name='mobile',content_type=ct).values_list('object_id',flat=True)
    stories = Story.published_objects.filter(id__in=ti)

但是,我只想要前 50 个故事。所以我做了什么:

    ct = ContentType.objects.get_for_model(Story)
    ti = TaggedItem.objects.filter(tag__name='mobile',content_type=ct).values_list('object_id',flat=True)
    ti50 = ti[:50]
    stories = Story.published_objects.filter(id__in=ti50)

在这里,我将列表本身切片为仅包含 50 个 ID,然后将切片列表提供给 __in 子句。所以我期待列表中有 50 个故事。但是,我得到了这个错误:

   DatabaseError: (1235, "This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'")

我不明白为什么在 MySQL 中使用 LIMIT,尽管我试图在 Python 本身中预先对其进行切片。 对此有何解释?

【问题讨论】:

    标签: python mysql django django-queryset


    【解决方案1】:

    您不是在“对列表进行切片”。 ti 仍然是一个查询集,切片本身仍然不评估它。所以当你把它放在 __in 子句中时,它仍然是一个代表未评估的数据库查询的对象。 Django 尝试在主 Story 查询中将其作为子查询传递,但正如错误消息所述,MySQL 不支持。

    如果您想传递 50 个 ID,则必须通过转换为列表来显式评估查询:

    ti50 = list(ti[:50])
    

    【讨论】:

      猜你喜欢
      • 2016-11-12
      • 2015-03-18
      • 2020-03-01
      • 2017-06-19
      • 1970-01-01
      • 2019-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多