0

I'm wondering if it is somehow possible to use "the inverse" of the __contains fields lookup.

https://docs.djangoproject.com/en/1.11/ref/models/querysets/#contains

So for example:

class Person(models.Model):
    ...
    last_name = models.CharField()

And with this Person model I could do for example the following query that'll return the Persons that have a last_name field that would fit in the string given:

>>> Person.objects.filter(last_name__contains='John Doe, Jane Roe, ...')
<QuerySet: [Person: Donald Doe]>
White
  • 134
  • 2
  • 9

1 Answers1

0

You can use:

import operator    
from functools import reduce
from django.db.models import Q  

Person.objects.exclude(reduce(operator.or_, (Q(last_name__contains=x) for x in ['John Doe', 'Jane Roe', '...'])))

is the same than:

Person.objects.exclude(Q(last_name__contains='Jhon') | Q(last_name__contains='Jane'))

you can change operator.or_ by operator.and_

Mauricio Cortazar
  • 4,049
  • 2
  • 17
  • 27
  • Well, this is looking for the Person objects that have either 'John Doe', 'Jane Roe' etc in their `last_name` field. So this is still not inverted unfortunately. – White Oct 18 '17 at 18:56
  • So what I eventually would like is the Person objects that for example have `last_name="Doe"` if I do `Person.objects.filter(last_name__invertedcontains="John Doe, Jane Roe")` (explicitly single string, though not important here) – White Oct 18 '17 at 18:58
  • @White srry I misunderstood the question let me correct – Mauricio Cortazar Oct 18 '17 at 19:00
  • @White see my edit, instead of use `filter` put `exclude` – Mauricio Cortazar Oct 18 '17 at 19:02
  • Sorry, now still it does only return objects with for example `last_name="John Doe"`. Annoying isn't? :=> – White Oct 18 '17 at 19:07
  • if the `last_name__contains="Jhon Doe"` it will return all the objects with the last name jhon doe it seems you are looking for doe last name, so it wont return it. In this case use `operator.and_` to exclude – Mauricio Cortazar Oct 18 '17 at 19:12