1079
You can use Q objects for this. They can be negated with the ~
operator and combined much like normal Python expressions:
from myapp.models import Entry
from django.db.models import Q
Entry.objects.filter(~Q(id=3))
will return all entries except the one(s) with 3
as their ID:
[<Entry: Entry object>, <Entry: Entry object>, <Entry: Entry object>, ...]
799
Your query appears to have a double negative, you want to exclude all rows where x
is not 5, so in other words you want to include all rows where x
is 5. I believe this will do the trick:
results = Model.objects.filter(x=5).exclude(a=True)
To answer your specific question, there is no "not equal to" field lookup but that’s probably because Django has both filter
and exclude
methods available so you can always just switch the logic around to get the desired result.
- [Django]-How do I use an UpdateView to update a Django Model?
- [Django]-How can I serialize a queryset from an unrelated model as a nested serializer?
- [Django]-How do I deploy Django on AWS?
167
the field=value
syntax in queries is a shorthand for field__exact=value
. That is to say that Django puts query operators on query fields in the identifiers. Django supports the following operators:
exact
iexact
contains
icontains
in
gt
gte
lt
lte
startswith
istartswith
endswith
iendswith
range
date
year
iso_year
month
day
week
week_day
iso_week_day
quarter
time
hour
minute
second
isnull
regex
iregex
I’m sure by combining these with the Q objects as Dave Vogt suggests and using filter()
or exclude()
as Jason Baker suggests you’ll get exactly what you need for just about any possible query.
- [Django]-How to implement followers/following in Django
- [Django]-Django – SQL bulk get_or_create possible?
- [Django]-Django url tag multiple parameters
158
There are three options:
-
results = Model.objects.exclude(a=True).filter(x=5)
-
Use
Q()
objects and the~
operatorfrom django.db.models import Q object_list = QuerySet.filter(~Q(a=True), x=5)
-
Register a custom lookup function
from django.db.models import Lookup from django.db.models import Field @Field.register_lookup class NotEqual(Lookup): lookup_name = 'ne' def as_sql(self, compiler, connection): lhs, lhs_params = self.process_lhs(compiler, connection) rhs, rhs_params = self.process_rhs(compiler, connection) params = lhs_params + rhs_params return '%s <> %s' % (lhs, rhs), params
Which can the be used as usual:
results = Model.objects.exclude(a=True, x__ne=5)
- [Django]-Cannot access django app through ip address while accessing it through localhost
- [Django]-How to run celery as a daemon in production?
- [Django]-Django: Error: You don't have permission to access that port
121
It’s easy to create a custom lookup, there’s an __ne
lookup example in Django’s official documentation.
You need to create the lookup itself first:
from django.db.models import Lookup
class NotEqual(Lookup):
lookup_name = 'ne'
def as_sql(self, compiler, connection):
lhs, lhs_params = self.process_lhs(compiler, connection)
rhs, rhs_params = self.process_rhs(compiler, connection)
params = lhs_params + rhs_params
return '%s <> %s' % (lhs, rhs), params
Then you need to register it:
from django.db.models import Field
Field.register_lookup(NotEqual)
And now you can use the __ne
lookup in your queries like this:
results = Model.objects.exclude(a=True, x__ne=5)
- [Django]-How to submit form without refreshing page using Django, Ajax, jQuery?
- [Django]-How to test "render to template" functions in django? (TDD)
- [Django]-Django-allauth social account connect to existing account on login
55
While you can filter Models with =
, __gt
, __gte
, __lt
, __lte
, you cannot use ne
or !=
. However, you can achieve better filtering using the Q object.
You can avoid chaining QuerySet.filter()
and QuerySet.exclude()
, and use this:
from django.db.models import Q
object_list = QuerySet.filter(~Q(field='not wanted'), field='wanted')
- [Django]-Detect mobile, tablet or Desktop on Django
- [Django]-Trying to migrate in Django 1.9 — strange SQL error "django.db.utils.OperationalError: near ")": syntax error"
- [Django]-How to submit form without refreshing page using Django, Ajax, jQuery?
30
Pending design decision. Meanwhile, use exclude()
The Django issue tracker has the remarkable entry #5763,
titled “Queryset doesn’t have a “not equal” filter operator”.
It is remarkable because (as of April 2016) it was
“opened 9 years ago” (in the Django stone age),
“closed 4 years ago”, and
“last changed 5 months ago”.
Read through the discussion, it is interesting.
Basically, some people argue __ne
should be added
while others say exclude()
is clearer and hence __ne
should not be added.
(I agree with the former, because the latter argument is
roughly equivalent to saying Python should not have !=
because
it has ==
and not
already…)
- [Django]-How to resize the new uploaded images using PIL before saving?
- [Django]-Running Django with FastCGI or with mod_python
- [Django]-Django Background Task
- [Django]-What is "load url from future" in Django
- [Django]-Switching to PostgreSQL fails loading datadump
- [Django]-Do django db_index migrations run concurrently?
16
You should use filter
and exclude
like this
results = Model.objects.exclude(a=true).filter(x=5)
- [Django]-Django index page best/most common practice
- [Django]-Django-Forms with json fields
- [Django]-Django form fails validation on a unique field
10
This will give your desired result.
from django.db.models import Q
results = Model.objects.exclude(Q(a=True) & ~Q(x=5))
for not equal you can use ~
on an equal query. obviously, Q
can be used to reach the equal query.
- [Django]-AccessDenied when calling the CreateMultipartUpload operation in Django using django-storages and boto3
- [Django]-How to run a celery worker with Django app scalable by AWS Elastic Beanstalk?
- [Django]-Best practices for getting the most testing coverage with Django/Python?
8
What you are looking for are all objects that have either a=false
or x=5
. In Django, |
serves as OR
operator between querysets:
results = Model.objects.filter(a=false)|Model.objects.filter(x=5)
- [Django]-How to delete project in django
- [Django]-Django models avoid duplicates
- [Django]-Error when using django.template
8
Django-model-values (disclosure: author) provides an implementation of the NotEqual lookup, as in this answer. It also provides syntactic support for it:
from model_values import F
Model.objects.exclude(F.x != 5, a=True)
- [Django]-How to customize activate_url on django-allauth?
- [Django]-Django: Implementing a Form within a generic DetailView
- [Django]-Django Sitemaps and "normal" views
7
results = Model.objects.filter(a = True).exclude(x = 5)
Generetes this sql:
select * from tablex where a != 0 and x !=5
The sql depends on how your True/False field is represented, and the database engine. The django code is all you need though.
- [Django]-Resource temporarily unavailable using uwsgi + nginx
- [Django]-How can I handle Exceptions raised by dango-social-auth?
- [Django]-Django Form File Field disappears on form error
- [Django]-Explicitly set MySQL table storage engine using South and Django
- [Django]-Django substr / substring in templates
- [Django]-Django models.py Circular Foreign Key
5
The last bit of code will exclude all objects where x!=5 and a is True. Try this:
results = Model.objects.filter(a=False, x=5)
Remember, the = sign in the above line is assigning False to the parameter a and the number 5 to the parameter x. It’s not checking for equality. Thus, there isn’t really any way to use the != symbol in a query call.
- [Django]-Using Cloudfront with Django S3Boto
- [Django]-Uwsgi installation error in windows 7
- [Django]-Celery missed heartbeat (on_node_lost)
2
Watch out for lots of incorrect answers to this question!
Gerard’s logic is correct, though it will return a list rather than a queryset (which might not matter).
If you need a queryset, use Q:
from django.db.models import Q
results = Model.objects.filter(Q(a=false) | Q(x=5))
- [Django]-Django celery task: Newly created model DoesNotExist
- [Django]-Django model blank=False does not work?
- [Django]-Django models.py Circular Foreign Key
1
If we need to exclude/negate based on the sub queryset we can use,
When a conditional expression returns a boolean value, it is possible to use it directly in filters. Here non_unique_account_type
returns a boolean value. But, still, we can use it in the filter.
>>> non_unique_account_type = Client.objects.filter(
... account_type=OuterRef('account_type'),
... ).exclude(pk=OuterRef('pk')).values('pk')
>>> Client.objects.filter(~Exists(non_unique_account_type))
In the SQL terms, it evaluates to:
SELECT * FROM client c0
WHERE NOT EXISTS (
SELECT c1.id
FROM client c1
WHERE c1.account_type = c0.account_type AND NOT c1.id = c0.id
)
- [Django]-Django – getting Error "Reverse for 'detail' with no arguments not found. 1 pattern(s) tried:" when using {% url "music:fav" %}
- [Django]-How do you Serialize the User model in Django Rest Framework
- [Django]-Django custom field validator vs. clean