42

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.

Daniel Gollás
  • 1,044
  • 2
  • 10
  • 18

3 Answers3

98

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")

ptim
  • 14,902
  • 10
  • 83
  • 103
Ludwik Trammer
  • 24,602
  • 6
  • 66
  • 90
7

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

Hank Gay
  • 70,339
  • 36
  • 160
  • 222
  • 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! – Daniel Gollás Feb 03 '10 at 20:04
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.

kibitzer
  • 4,479
  • 1
  • 21
  • 20