Django 在不使用字段查找的情况下从查询集中排除特定实例

Posted

技术标签:

【中文标题】Django 在不使用字段查找的情况下从查询集中排除特定实例【英文标题】:Django excluding specific instances from queryset without using field lookup 【发布时间】:2011-03-03 04:55:38 【问题描述】:

我有时需要确保从查询集中排除某些实例。 这是我通常这样做的方式:

unwanted_instance = MyModel.objects.get(pk=bad_luck_number)
uninteresting_stuff_happens()
my_results = MyModel.objects.exclude(id=unwanted_instance.id)

或者,如果我有更多:

my_results = MyModel.objects.exclude(id_in=[uw_in1.id, uw_in2.id, uw_in3.id])

这“感觉”有点笨拙,所以我试了一下:

my_ideally_obtained_results = MyModel.objects.exclude(unwanted_instance)

这不起作用。但我读到here on SO 可以将子查询用作排除参数。 我运气不好?我是否缺少某些功能(检查了文档,但没有找到任何有用的指针)

【问题讨论】:

【参考方案1】:

你已经在做的方式是最好的方式。

如果您正在寻找一种与模型无关的方法,请不要忘记您可以使用query.exclude(pk=instance.pk)

顺便说一句,如果 Django 的 ORM 有一个身份映射器(目前还没有),那么您将能够执行类似 MyModel.objects.filter(<query>).all().remove(<instance>) 的操作,但您已经出局了在这方面运气。你做这件事的方式(或上面的那个)是你所拥有的最好的。

哦,你还可以比 in 使用列表理解查询做得更好:query.exclude(id__in=[o.id for o in <unwanted objects>])

【讨论】:

另外,如果您有要排除的查询集(例如MyModel.objects.filter(<exclude-query>)),您可以使用ValuesQuerySet 获取ID,如下所示:id_dicts = MyModel.objects.filter(<exclude-query>).values('id') 然后query.exclude(id__in=[item['id'] for item in id_dicts]) 我只是想在@RacingTadpole 的建议中添加一些内容:您可以轻松地使用values_list( "id", flat = True ) 来获取所有ID 的顺序列表。但是这会影响数据库,所以我建议使用 Python 的列表理解。【参考方案2】:

给定的答案是完美的,试试这个对我来说很好

步骤 1)

 from django.db.models import Q

步骤 2)

 MyModel.objects.filter(~Q(id__in=[o.id for o in <unwanted objects>]))

【讨论】:

使用Q 表达式比.exclude(id__in=[o.id for o in &lt;unwanted objects&gt;]) 更好吗? 这是实现相同目标的另一种替代解决方案 这似乎是一个非常低效的替代方案。 这在blocks = self.blocks.filter(~Q(image='') | Q(~Q(video='') &amp; Q(loop=True)))这样的场景中效果很好【参考方案3】:

您可以将不需要的项目放在一个列表中,然后获取除列表中的项目之外的所有项目,如下所示:

MyModel.objects.exclude(id__in=[id1,id2,id3 ])

【讨论】:

这在问题中明确说明是我尝试过的事情之一。我正在寻找替代解决方案!

以上是关于Django 在不使用字段查找的情况下从查询集中排除特定实例的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用 Sybase/Perl 中的游标的情况下从表/文件中的 2 行中获取结果集中的一行

如何在不使用自动模型表单的情况下从 Django 的文本框中获取数据?

Selenium 在不使用 XPath 的情况下从已经给定的元素中查找近元素

如何在不使用 CURDATE、MONTH、YEAR 等 DATE 函数的情况下从 RDBMS 获取当前月份记录

如何在不保留唯一数字输入功能的情况下从 Django integerField 中删除箭头?

如何在不使用字段名的情况下运行 django orm 查询?