切片查询集与切片__in子句中使用的列表相同吗?无法理解这种行为

时间:2014-10-02 20:02:57

标签: python mysql django django-queryset

我有一个Story模型,其中包含一个TagField到django-tagging app。 我正在获取特定标签的故事列表。在功能上我的代码工作正常,但我遇到了一个我无法理解的行为。

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

    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'")

我不明白为什么LIMIT在MySQL上使用,虽然我试图在Python本身预先切片。 对此有何解释?

1 个答案:

答案 0 :(得分:0)

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

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

ti50 = list(ti[:50])