#25113 closed New feature (wontfix)
Field lookup for __not_in
| Reported by: | Evan Tschuy | Owned by: | nobody |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | dev |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Making a query where I can get all of the objects matching a certain list is quite useful. However, Django currently doesn't allow me to get objects that DON'T match a list:
test = ProductPreparation.objects.filter(product=product, preparation__id__not_in=preparations)
I feel like adding a field lookup for __not_in would be helpful. I've created a pull request on Github:
https://github.com/django/django/pull/4984
I've not added any tests to it, as I couldn't find any tests for __in, and don't quite know how to test an entire field lookup. Apologies; would love pointers.
Change History (8)
comment:1 by , 10 years ago
| Description: | modified (diff) |
|---|
comment:2 by , 10 years ago
| Description: | modified (diff) |
|---|
comment:3 by , 10 years ago
| Description: | modified (diff) |
|---|
comment:5 by , 10 years ago
| Resolution: | → wontfix |
|---|---|
| Status: | new → closed |
ah, chaining it like so:
test = ProductPreparation.objects.filter(product=product).exclude(preparation__id__in=preparations)
Of course. Thanks! I'll go ahead and close the ticket.
comment:6 by , 6 years ago
It produce SQL like:
NOT ("jobs_job"."id" IN (SELECT U0."id" FROM "jobs_jobstatus" U0))
which may not be equivalent to
"jobs_job"."id" NOT IN (SELECT U0."id" FROM "jobs_jobstatus" U0)
regarding performance.
Also because of "weird" chained filter() behavior ( https://docs.djangoproject.com/en/dev/topics/db/queries/#spanning-multi-valued-relationships ) you will have to do something like
Job.objects.filter(
~Q(id__in=JobStatus.objects.values_list('id', flat=True).all()),
...
)
instead of
Job.objects.filter(...).exclude(id__in=JobStatus.objects.values_list('id', flat=True).all()).delete()
comment:7 by , 6 years ago
I ran into this same issue. As the comment above points out, NOT (id IN ()) is not equivalent to id NOT IN (). Details of my issue and attempts are here:
The solution provided on that post, and another provided on Django's forum, seem like a reasonable addition to Django. Lacking support for the equivalent of SQL's id NOT IN (1, 2, 3) is a hole in the ORM feature set, especially now that we have Subquery.
comment:8 by , 6 years ago
From my point of view this feature would have the same flaws as the wontfixed __ne lookup request (#5763) and thus should follow the same resolution.
Using
.exclude()withinlookup (.exclude(id__in=[...])) will be enough instead of creating new API