Django QuerySet直接访问外键字段,无需强制连接

时间:2010-11-15 21:46:28

标签: django django-queryset

假设您有一个模型Entry,其中一个字段“author”指向另一个模型Author。假设此字段可以为空。

如果我运行以下QuerySet:

Entry.objects.filter(作者= X)

其中X是某个值。假设在MySQL中我已经在Entry上为其他一些列和author_id设置了复合索引,理想情况下我希望SQL在Entry模型上使用“author_id”,以便它可以使用复合索引。

事实证明,Entry.objects.filter(author = 5)可以工作,没有连接完成。但是,如果我说author = None,Django会与Author进行连接,然后添加到Where子句Author.id IS NULL。所以在这种情况下,它不能使用复合索引。

有没有办法告诉Django只检查pk,而不是按照链接?

我知道的唯一方法是在QuerySet中添加一个额外的.extra(where = ['author_id IS NULL']),但我希望.filter()中的一些魔法可以工作。

感谢。

(对不起,我之前对此并不清楚,感谢lazerscience和Josh的回答。)

5 个答案:

答案 0 :(得分:1)

这不能按预期工作吗?

Entry.objects.filter(author=X.id)

您可以在外键过滤器中使用模型或模型ID。如果这会执行单独的查询,我无法立即检查,但我真的希望它不会。

答案 1 :(得分:1)

如果按照您的描述进行操作并且不使用select_related() Django根本不会执行任何连接 - 无论您是否过滤相关对象的主键或相关对象(不进行任何操作)差)。

您可以尝试:

print Entry.objects.(author=X).query

答案 2 :(得分:1)

假设Author的外键名为author_id,(如果没有为ForeignKey字段指定外键列的名称,则应为NAME_id,如果指定了名称,则检查模型定义/您的数据库架构),

Entry.objects.filter(author_id=value)

应该有用。

答案 3 :(得分:0)

第二次尝试:

http://docs.djangoproject.com/en/dev/ref/models/querysets/#isnull

也许你可以拥有一个单独的查询,具体取决于X是否为空author__isnull

答案 4 :(得分:0)

很晚,但我刚碰到这个。我正在使用Q个对象来构建查询,所以在我的情况下这很好用:

~Q(author_id__gt=0)

这会生成类似

的sql
NOT ("author_id" > 0  AND "author_id" IS NOT NULL)

您可以使用

解决此问题中的问题
Entry.objects.exclude(author_id__gt=0)