Django query negation
Asked Answered
B

3

43

I know how to build filters and Q objects in django, but I don't know how to negate the operators that the API provides, for example for the contains operator I would like something like notcontains.

e.g.

q=Q(name__notcontains="SomeString")

This would get me all objects whose name do not contain "SomeString".

Is there some syntax that I'm missing?

Thankyou.

Bendwise answered 3/2, 2010 at 19:43 Comment(0)
F
100

You can use exclude() in place of filter():

Entry.objects.exclude(name__contains="SomeString")

("give me all entries EXCEPT those with names containing "SomeString")

And when dealing with Q object you can use "~" symbol before Q object to represent negation. For example the following statement means "give me all Entries with names containing "Elephant", but NOT containing "SomeString":

Entry.objects.filter(Q(name__contains="Elephant") & ~Q(name__contains="SomeString"))

In some cases you may want to use both methods:

Entry.objects.exclude(Q(name__contains="Elephant") & ~Q(name__contains="SomeString"))

("give me all entries, EXCEPT those with names containing "Elephant", but NOT containing "SomeString")

Furnishing answered 3/2, 2010 at 19:59 Comment(0)
D
7

Here's the QuerySet API reference. exclude seems to do what you want.

Dioxide answered 3/2, 2010 at 19:47 Comment(1)
Great! that is exactly what I needed, although it can't be used inside a Q object, one can simply chain the filters together: q=Q(title__contains="SomeTerm") TheModel.objects.filter(q).exclude(title__contains="SomeTermWeDontWant") Thanks!Interracial
T
3

Either use exclude as Hank suggests or, for the particular contains case, use Q(name__regex=r'!(SomeString)') if you really really need to use the filter. Be warned though that regex is not database-agnostic, check what syntax your db supports first.

Twist answered 3/2, 2010 at 20:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.