Django从查询集中排除特定实例而不使用字段查找

Ago*_*gos 35 django filtering django-queryset

有时我需要确保某些情况下是从查询集排除.
这是我通常这样做的方式:

unwanted_instance = MyModel.objects.get(pk=bad_luck_number)
uninteresting_stuff_happens()
my_results = MyModel.objects.exclude(id=unwanted_instance.id)
Run Code Online (Sandbox Code Playgroud)

或者,如果我有更多的:

my_results = MyModel.objects.exclude(id_in=[uw_in1.id, uw_in2.id, uw_in3.id])
Run Code Online (Sandbox Code Playgroud)

这'感觉'有点笨重,所以我试过:

my_ideally_obtained_results = MyModel.objects.exclude(unwanted_instance)
Run Code Online (Sandbox Code Playgroud)

哪个不起作用.不过,我看到这里的SO是一个可以使用子查询作为参数排除.
我运气不好吗?我缺少一些功能(检查文档,但没有发现任何有用的指针)

obe*_*tie 71

你已经这样做的方式是最好的方式.

如果这是一种与模型无关的方式,你正在寻找,不要忘记你可以做到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']为id_dicts中的项目])`. (3认同)
  • 差不多4年后,这个答案解决了我的问题.:-) (2认同)
  • 我只想在@ RacingTadpole的建议中添加一些东西:你可以轻松地使用`values_list("id",flat = True)`获得所有ID的顺序列表.然而,这将击中DB,所以我建议使用Python的列表理解. (2认同)

kar*_*eek 6

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

步骤1)

 from django.db.models import Q
Run Code Online (Sandbox Code Playgroud)

第2步)

 MyModel.objects.filter(~Q(id__in=[o.id for o in <unwanted objects>]))
Run Code Online (Sandbox Code Playgroud)

  • 如何使用`Q`表达式比`.exclude(id__in = [o.id for <in <objects objects>])? (9认同)